weixin_42299201 2008-12-22 15:46
浏览 167
已采纳

Socket通信的一个奇怪现象,大家一起来看看

通信模型:



1.客户端发送76字节的封包

2.服务器收到76字节封包、返回2133字节封包到客户端

3.客户端收到2133字节封包、返回16字节封包做响应

4.客户端发送76字节封包

5.服务器端收到16字节封包,不做处理

6.回到2的操作



运行环境:

Java1.5

局域网(本机测试不会发生下面的问题)



现象:

1.使用上面的通信模型,客户端两次发出76字节封包的间隔需要40ms之久(依网络情况而定)

2.如果将将第3步的后半部分去掉,即客户端不发送16字节响应,客户端两次发送76字节封包的间隔变成只有0-1ms

3.如果第3步不变,使服务器端收到16字节封包后随便给客户端回应个什么,那么客户端两次发送76字节封包的间隔也变成了0-1ms



总之,如果客户端与服务器端的封包是一一对应的话,速度将很快。如果客户端发3个包,服务端响应一次的话,速度将非常慢。



不知道是JAVA本身的问题,还是TCP的机制本就如此?



下面是服务器端和客户端代码:



Client.java

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

public class Client {

/**
 * @param args
 */
public static void main(String[] args) throws Exception{

    Socket socket = new Socket();
    System.out.println("Connecting...");
    socket.connect(new InetSocketAddress(InetAddress.getByName("10.2.2.141"),9999));

    System.out.println("Connected.");

    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    out.write(new byte[76]);
    out.flush();

    int i = 0;
    long t = System.currentTimeMillis();

    byte[] delivery = new byte[2133];

    while(in.read(delivery) != -1){

        // 16字节响应,如果不发送响应,通信速度将大幅提升
        out.write(new byte[16]);
        out.flush();

        out.write(new byte[76]);

        out.flush();

        if(++i % 100 == 0){//计算两次发送76字节封包间的平均时间
            System.out.println("TIME: " + (System.currentTimeMillis() - t) / 100);
            t = System.currentTimeMillis();
        }


    }

}

}





TServer.java

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class TServer {

public static void main(String[] args) throws Exception{
    ServerSocket ss = new ServerSocket();

    System.out.println("Server starting...");
    ss.bind(new InetSocketAddress(InetAddress.getByName("10.2.2.141"), 9999));

    Socket socket = ss.accept();
    System.out.println("Client connected: " + socket.getRemoteSocketAddress());

    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    int r = 0;
    byte[] b = new byte[2048];
    while((r = in.read(b)) != -1){
        if(r == 76){
            System.out.println("GET");
            out.write(new byte[2133]);
            System.out.println("DELIVERY");
        }else if(r == 16){
            System.out.println("RESP");
            //如果收到16字节封包后随便回应点东西给客户端,速度也将大幅提升
            //out.write(new byte[2133]);
        }
    }
}

}



  • 写回答

1条回答 默认 最新

  • 不良校长 2008-12-22 15:46
    关注

    set tcpNoDelay=true in socket opt both server and client side.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件