通信模型:
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]); } } }
}