现在遇到个问题,我们这边是做客户端的。服务器端是socket,不是我们写的,看不到源码,走的是tcp协议。我们的socket客户端在接收大数据(大约大于5000个byte)的时候总是不能一次性的接收所有的数据,一般是分2次。可能是1000,4000;2000,3000;4000,1000这样不固定的。但有个奇怪的现象,在debug的时候,数据是能一次收完整的。后来发现只要在xx。read(buffer)之前sleep几秒,数据就全了。现在不明白为什么会这样,以及怎么解决。听说tcp协议会保证数据包的顺序和完整性吗?现在数据的顺序是对的,但不完整。因为开发机是不能上网的,所以我贴不了代码。客户端用的是nio,写法我看了下是网上很常见的那种。
------解决方案--------------------------------------------------------
其实你这并不是问题,只是你疑惑而已,当你清楚Socket的工作原理后,你就不会疑惑了。
Socket里的inputStream和outputStream是负责Socket的输入和输出,并且他们都是阻塞的,除非关闭Socket或者shutdown对应的Stream。
为什么你sleep几秒后数据就全了呢?因为数据在Socket上是边传边收,而不是传完了再收,这是你理解的一个误区,所以我建议你们在传输数据的时候,能在头几位(这里是指byte)指明后面要接受的数据的长度,用read(buf,offset,len)方法肯定可以完整得到你想要的数据,不需要sleep(如果数据够大的话,sleep也是解决不了问题的)。或者你可以用一组约定字符表示结束,一直读到约定字符为止。
------解决方案--------------------------------------------------------
TCP包的大小是有限制的,网络端口的缓存也有大小。
所以,如果你用普通SOCKET读数据,如果所续数据未收到,肯定会阻塞。
------解决方案--------------------------------------------------------
最好修改下服务端。
就像楼上们说的,传输的数据有个一标志位,标志传输数据的总长度。这样在服务端接收时去判断这个标志位,如是收到了指定长度的时间则停止接收,如果长度不够,则循环接收,直到全部接收为止。
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------
顺便问下,如果服务器端连续发送aaa和bbb两段报文。那接收方会不会收到bababa?
——绝对不会,但是可能会收到 3 组报文: aa ab bb
如果用长度来控制读取的长度,是不是要发送2次
——这是比较靠谱的做法