1:异步通讯,一个线程进行发,一个线程收,发送的包和收到的包通过一个msgid来关联。
2:和服务器建立长连接;
3:收,发的包的前四个字节是一个int,用于说明此次传输的总长度,先readint,然后在根据长度说 明去循环读服务器发过来的东东。
问题:
大多数情况下,收发的数据都是1k左右,在这种情况下一切正常。偶尔,会有长达10k的包发过来,这时候问题来了:..........
                 byte[] receivedData;
int dataSize;
dataSize = in.readInt();

// 注意:recievedata 不包含消息包长度这四个字节
logger.info("len from server:" + dataSize);
receivedData = new byte[dataSize - 4];
int dataTotalSizeToRead = dataSize - 4;
int dataToReadLeft = dataSize - 4;
int dataThisTimeRead;
while (dataToReadLeft > 0) {
// 一直读到指定数目的字节为止
dataThisTimeRead = in.read(receivedData, dataTotalSizeToRead
- dataToReadLeft, dataToReadLeft);
dataToReadLeft -= dataThisTimeRead;
                    ..........}
比如服务器发一个85000bytes的包过来(我读到它的包长度说明。),然后我进入while循环,每次都吧读到的长度打印出来:
2044
10220
2015
这样读了几次之后,每次只能读到219个byte(而219正是服务器给我的心跳包返回的响应长度),
累加的长度还远远小于85000。由于此时另外一个线程又在不停的发心跳测试包,每个心跳包的长度是219,发现似乎os把前面85000个byte中未读剩下的东东都丢掉了,而是在接收心跳包的响应了。持续几秒之后,服务器就把socket关闭了,导致我这边出错。请问怎样防止os在流量太多的时候,把前面收到的内容自动丢弃!!似乎它为了将后面收到的小包放到接收缓冲区里面,而把前面收到的85000字节中我应用程序尚未读完的东东丢弃了。我设置了socket的revievebuffer,但是没有起到任何作用!
谢谢各位帮助!

解决方案 »

  1.   

    为什么对方一次send80k的东东过来,我的socket就会出错。对方的write函数会报错!对方说是我这边不能接收导致的。
    求救!
      

  2.   

    在通信层,发包和收包不一定是对等的。TCP只是保证数据一定从发送方按发送的先后持续到接收方,但不能保证每次接受包的阶段情况是一样的。如:
    发送:1234567890 1234567890 1234567890 1234567890
    接收:1234567890 12345678901234567 890123456 7890 因此,在你那些大包很可能看上去是发送一次,分了两次接受;小包可能发了两次,接受方只接受了一个含两个小包的大数据。