C/S模式,SOCKET TCP连接,服务端给客户端发数据,客户端只收到了一部分,这是为什么呢?

时间:2021-03-07 18:00:56
C/S模式
SOCKET TCP 连接

服务端有一个循环,但循环次数不确定,每循环一次向客户端发一个包,包的大小为2000字节。
比如现在确定服务端已经循环了十次,发了十个包,但是客户端收到的包并不全,只是其中的几个。

客户端接收数据时的缓冲区为2048字节。

大家帮忙看看是为什么呢,谢谢各位啦!

8 个解决方案

#1


tcp是可靠的
用抓包软件,看看网卡上发了多少,接收多少,再分析

#2


楼上的哥,感觉是不是缓冲区的问题,或者是发的太快,接的太慢了,如果是这个问题,又不知道如何下手。

#3


典型的毡包问题了。当你快数发送数据时,Sokcet底层会为你重新组包。
也就是说,发送端你调用M次Send发送数据,接收端不一定非得调用M次Recv来接受数据。
有可能接收端调用一次Recv就能接受完你所有发送的数据,也就是说你发送的数据都在缓冲去了。
recv返回值为接收到的字节数

#4


你接收端的问题吧,因为看ls的回到。。

#5


哥们,继续顶啊。

#6


引用 3 楼 tttyd 的回复:
典型的毡包问题了。当你快数发送数据时,Sokcet底层会为你重新组包。
也就是说,发送端你调用M次Send发送数据,接收端不一定非得调用M次Recv来接受数据。
有可能接收端调用一次Recv就能接受完你所有发送的数据,也就是说你发送的数据都在缓冲去了。
recv返回值为接收到的字节数


同意。
我的解决办法是给数据加上一个自己定义的协议,即使接收端接收一次就收到十个数据包的话,你可以根据自己的协议区别开每个数据包。

#7


问题在于:不一定你发10次,10次就能接收完!

   首先,发送端用200(也可以是其他固定长度)的缓冲区发送你要发送数据的长度过去;接收端用200的缓冲区接收一次,然后申请足够大小的缓冲区来准备接收发送端的数据。
   发送端:每次发送都判断实际发送数据长度(并不一定是你的发送缓冲区的大小),总数据长度减去该次发送数据的长度。循环,直到发送长度为0;
   接收端:每次接收都判断实际接收数据的长度(并不一定是你的接收缓冲区的大小),累加接收数据的长度。循环,直到接收完数据。

#8


问题已解决,非常感谢各位,特别是 silverpot 同志!

现在也是按你的那种方法来的,只不过没有重新定义一个协议,因为这边发的所有数据都是同一个结构体类型,所以只需要在发的时候把要发的数据拷贝到这个结构体内,在收的时候recv这个结构体大小个字节流,然后拷贝到对应该结构体的对象中就可以了。

#1


tcp是可靠的
用抓包软件,看看网卡上发了多少,接收多少,再分析

#2


楼上的哥,感觉是不是缓冲区的问题,或者是发的太快,接的太慢了,如果是这个问题,又不知道如何下手。

#3


典型的毡包问题了。当你快数发送数据时,Sokcet底层会为你重新组包。
也就是说,发送端你调用M次Send发送数据,接收端不一定非得调用M次Recv来接受数据。
有可能接收端调用一次Recv就能接受完你所有发送的数据,也就是说你发送的数据都在缓冲去了。
recv返回值为接收到的字节数

#4


你接收端的问题吧,因为看ls的回到。。

#5


哥们,继续顶啊。

#6


引用 3 楼 tttyd 的回复:
典型的毡包问题了。当你快数发送数据时,Sokcet底层会为你重新组包。
也就是说,发送端你调用M次Send发送数据,接收端不一定非得调用M次Recv来接受数据。
有可能接收端调用一次Recv就能接受完你所有发送的数据,也就是说你发送的数据都在缓冲去了。
recv返回值为接收到的字节数


同意。
我的解决办法是给数据加上一个自己定义的协议,即使接收端接收一次就收到十个数据包的话,你可以根据自己的协议区别开每个数据包。

#7


问题在于:不一定你发10次,10次就能接收完!

   首先,发送端用200(也可以是其他固定长度)的缓冲区发送你要发送数据的长度过去;接收端用200的缓冲区接收一次,然后申请足够大小的缓冲区来准备接收发送端的数据。
   发送端:每次发送都判断实际发送数据长度(并不一定是你的发送缓冲区的大小),总数据长度减去该次发送数据的长度。循环,直到发送长度为0;
   接收端:每次接收都判断实际接收数据的长度(并不一定是你的接收缓冲区的大小),累加接收数据的长度。循环,直到接收完数据。

#8


问题已解决,非常感谢各位,特别是 silverpot 同志!

现在也是按你的那种方法来的,只不过没有重新定义一个协议,因为这边发的所有数据都是同一个结构体类型,所以只需要在发的时候把要发的数据拷贝到这个结构体内,在收的时候recv这个结构体大小个字节流,然后拷贝到对应该结构体的对象中就可以了。