java - 为什么我的 TCP 系统比 UDP 系统快?

标签 java sockets tcp udp

我有两个(客户端-服务器-客户端)系统。第一个使用 TCP,第二个使用 UDP。有趣的是,在传输 5-6 MB 的文件时,我使用 TCP 的系统比使用 UDP 的系统更快。出现问题是因为我的编码错误还是会发生?

TCP 客户端

   try {
       socket = new Socket("localhost", 7755);
   } catch (Exception e) {
       System.out.println(e.getMessage().toString());
   }

   out = new PrintWriter(socket.getOutputStream(), true);

   int i = 0;

   while (file.hasNext()) {
       String line = file.nextLine();
       if (!line.isEmpty()) {
           out.println(line);
       }
       i++;
   }

TCP 服务器

     try {
          serverSocketA = new ServerSocket(7755);
          serverSocketB = new ServerSocket(7760);
     } catch (Exception e) {
          System.out.println("Port error!");
     }
     System.out.println("Server is ready...");
     clientSocketA = serverSocketA.accept();
     clientSocketB = serverSocketB.accept();

     PrintWriter out = new PrintWriter(clientSocketB.getOutputStream(), true);

     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocketA.getInputStream()));

     while((dataFromClientA = in.readLine()) != null) {
          out.println(dataFromClientA);
     }

UDP 服务器

private static byte[] buf = new byte[6];
static Scanner file;

public static void main(String[] args) throws IOException{
    long startTime = System.currentTimeMillis();
    socket = new DatagramSocket();
    address = InetAddress.getByName("localhost");
    file = new Scanner(new File("sentfile.txt"));
    DatagramPacket packet;
    while (file.hasNext()) {
        String line = file.nextLine();
        if (!line.isEmpty()) {
            buf = line.getBytes();
            packet = new DatagramPacket(buf, buf.length, address, 7765);
            socket.send(packet);
        }
    }

UDP 客户端

private static byte[] buffer = new byte[6];
private static byte[] buffer2 = new byte[6];
private static boolean running;
static PrintWriter writer;

public static void main(String[] args) throws IOException {
    udpSocketB = new DatagramSocket();
    address = InetAddress.getByName("localhost");
    udpSocketA = new DatagramSocket(7765);
    running = true;
    DatagramPacket packet;
    while(running) {
        packet = new DatagramPacket(buffer, buffer.length);
        udpSocketA.receive(packet);
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        packet = new DatagramPacket(buffer, buffer.length, address, port);
        String received = new String(packet.getData(), 0, packet.getLength());
        DatagramPacket packetToB;
        buffer2 = received.getBytes();
        packetToB = new DatagramPacket(buffer2, buffer2.length, address, 7770);
        udpSocketB.send(packetToB);
        if (received.equals("end")) {
            running = false;
            continue;
        }
    }

我只是添加了 client1 和 server 代码,其余类似。可能是什么原因?

最佳答案

当您在 TCP 套接字上写入时,它会尽可能将字节合并为大约 1500 字节的 MTU 数据,从而使数据包 header 的开销相对较小。

当您将每一行写入其自己的 UDP 数据包时,每行都会产生开销,可能比实际发送的数据更多。

注意:在这两种情况下,您都不需要一次阅读一行。您可以一次读取 1 KB 的 byte[] 并打印它。

public class TCPClient {
    public static void main(String[] args) throws IOException {
        try (Socket socket = new Socket("localhost", 7755);
             FileInputStream fis = new FileInputStream(args[0])) {
            byte[] bytes = new byte[1024];
            OutputStream out = socket.getOutputStream();
            for (int len; (len = fis.read(bytes)) > 0; ) {
                out.write(bytes, 0, len);
            }
        }
    }
}

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(7755);
        System.out.println("Server is ready...");
        try (Socket socket = serverSocket.accept()) {
            byte[] bytes = new byte[1024];
            for (int len; (len = socket.getInputStream().read(bytes)) > 0; )
                System.out.write(bytes, 0, len);
        }
    }
}

您可以使用 UDP 做同样的事情,一次传输 1 KB 并获得类似的吞吐量。

注意:UDP 是有损的,因此您可能会丢失数据包,或者让它们乱序。

关于java - 为什么我的 TCP 系统比 UDP 系统快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51388062/

相关文章:

java - 我如何输出来控制台我的请求的正文

java - 我如何使用 hibernate 设置表和行的编码

sockets - 一台机器上的两个(或更多)套接字客户端连接

java - JMockit:验证被测试类实例的方法调用

java - FragmentTransaction 引起的 Android Studio NullPointerException

python - Tor、Stem 和套接字 - 使用 TOR 改变身份

Java 的 readInt() 在 C 中是否等效?

java - 即时通讯工具 TCP 或 UDP 哪个更好?

tcp - 服务器收到客户端的SYN后立即发送SYN/ACK

linux - 双向套接字到 TCP 通信