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 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥50 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥15 state显示变量是字符串形式,但是仍然红色,无法引用,并显示类型不匹配
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗