Windows Socket 大数据量时丢包问题? 本帖最后由 VisualEleven 于 2012-04-20 10:47:32 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 使用select,和不使用select(循环的去reve各个scoket),也都发生丢数据。估计和缓冲区来不及写或者~~有关系。 TCP又怎么会丢数据呢? send的返回值是否等于发送长度? 有没有这个检测? 还有, 你的包的格式是怎样的? 不会是 开始-内容-结束 的格式吧? 发送的内容最好用 长度 - 内容 - 长度 - 内容, 采用这种方式来读TCP的流才会是无丢包的 谢谢楼上的回复。我发送的包特别简单:"Test Message(ID: %d)&",(这个%d会替换成具体的数字,从1到10000)。10个子线程都这样发送。Server端收到后,再把消息显示到console上,格式是:Received (Test Message(ID: **))(Total: %d),(**就是发送时的ID,Total的%d就是接收到的消息总数)我考虑到了连包情况,所以在发送的消息最后有个&,收到消息后会简单的统计&来确定收到的消息数量。所以正确的话,最后肯定会收到10个这样的消息:Received (Test Message(ID: 10000))(Total: 99991)Received (Test Message(ID: 10000))(Total: 99992)Received (Test Message(ID: 10000))(Total: 99993)Received (Test Message(ID: 10000))(Total: 99994)Received (Test Message(ID: 10000))(Total: 99995)Received (Test Message(ID: 10000))(Total: 99996)Received (Test Message(ID: 10000))(Total: 99997)Received (Test Message(ID: 10000))(Total: 99998)Received (Test Message(ID: 10000))(Total: 99999)Received (Test Message(ID: 10000))(Total: 100000)(这10条消息不一定连续,但顺序肯定是以total后面的数字排序,这个都懂的~~)问题我测试了很多次,发生频率太快的话,总会丢失几百个包,也就是说console上最后一条消息可能是这样的:Received (Test Message(ID: 9950))(Total: 99654),(9950,99654都是随便举例子的,意思是总数没有到10万,收下来的包少了346个。)而如果发送方,每次发送一条,Sleep(1000),就不会丢包。TCP不丢包这个我懂,我怀疑是Server来不及接收,缓冲区出问题了。这种极端的情况,不是普通的理论能说明问题的,需要实际的尝试和经验,以及深层次的技术理解。***********************************************补充说明,1)我这个应用场景,不会有很多的Socket客户端,10多个,几十个最多了。但是每个客户端发送数据的频率可能极快,而且可能会持续一小段时间。2)我的socket,server端和client端做没做异步设置,情况都一样。 TCP ? 接收端接收数据有问题吧? TCP不会丢包,只会粘包。但是TCP发送的数据,不一定会全部成功的发送过去,你得检查send的返回值,如果一次发送不是全部都成功,就得循环发送。接收端那里,得把所有数据接收过来组包,不能丢弃部分数据 消息显示到console上非常的耗时,可能是处理速度跟不上。你试着写到文件里试一下,或者用其它方法去判定。还有缓冲区一定要够大,不然速度跟不上时会丢数据。 不知道LZ在服务器端用的是什么网络模型,你可以不用把接受的数据马上打印下来。只要放到一个10万大小的一个数组里即可,每次收到一个id,就把对应的位置标记一下。服务器判断数组内容有重复的时候,就是出错了。判断数组已经满了,就是接受成功了。如果服务器是多线程,注意一下同步数据的问题。 谢谢各位先~~其实我最开始也没有把每条消息都显示到console上,而是简单的统计收到的数量,就是发现数量不正确,才把消息显示出来的。send这边,我还真没有很严格每次去做检查,只是判断返回值“正常”就计数加1,这样下来最后10个子进程都是成功发送10000。这个问题下周一再完善一下。现在主要是我还不是特别精通Socket 接口函数,和内核在收发数据时的内部过程,所以无法判断问题根源。短时间去整这个也来不及。所以很想听听大家有没有遇到过类似的情况。对了,我还要补充一个调试测试时发现的重要现象:如果不是多个客户端,只有一个客户端(也就是说我的应用中只有1个子进程),再怎么快的发送数据(不要Sleep),服务端也能全部正确接收。我想,从Server的接收频率来说,1个客户端不Sleep的发送,频率应该比10的客户端Sleep(1)的间隔发送的频率要高。那为什么1个客户端的时候Server就正确了呢。我感觉这个问题还是有点价值的,也希望大家能一起讨论一下,相互学习。也想过用完成端口来试试,但是暂时不想去折腾那个。 还是晒出你的代码吧. 根据上述情况, 百分之百是出现在你解释粘包和发送包的过程有问题.底层的TCP传送是不会存在问题的, 更何况是单机 请问构造函数后面的throw()含义 在MFC程序中有什么方法能改变某个磁盘的图标呢 HOOK 不住一些进程的API是怎么回事 来着有分 在win32dll中怎样调用线程啊? 关于学习VC6/VC2005的2个问题。 关于在VC中编写DLL出现的问题 请帮我获得进程程序的的长文件名? 图像相加算法 请问??那里可以下载华康浏览器 socket的问题 网络编程遇到诡异错误,头文件为什么会出错? C++,HWND怎么强制转换成int类弄
估计和缓冲区来不及写或者~~有关系。
我发送的包特别简单:"Test Message(ID: %d)&",(这个%d会替换成具体的数字,从1到10000)。
10个子线程都这样发送。
Server端收到后,再把消息显示到console上,格式是:Received (Test Message(ID: **))(Total: %d),(**就是发送时的ID,Total的%d就是接收到的消息总数)
我考虑到了连包情况,所以在发送的消息最后有个&,收到消息后会简单的统计&来确定收到的消息数量。
所以正确的话,最后肯定会收到10个这样的消息:
Received (Test Message(ID: 10000))(Total: 99991)
Received (Test Message(ID: 10000))(Total: 99992)
Received (Test Message(ID: 10000))(Total: 99993)
Received (Test Message(ID: 10000))(Total: 99994)
Received (Test Message(ID: 10000))(Total: 99995)
Received (Test Message(ID: 10000))(Total: 99996)
Received (Test Message(ID: 10000))(Total: 99997)
Received (Test Message(ID: 10000))(Total: 99998)
Received (Test Message(ID: 10000))(Total: 99999)
Received (Test Message(ID: 10000))(Total: 100000)
(这10条消息不一定连续,但顺序肯定是以total后面的数字排序,这个都懂的~~)
问题我测试了很多次,发生频率太快的话,总会丢失几百个包,也就是说console上最后一条消息可能是这样的:
Received (Test Message(ID: 9950))(Total: 99654),
(9950,99654都是随便举例子的,意思是总数没有到10万,收下来的包少了346个。)
而如果发送方,每次发送一条,Sleep(1000),就不会丢包。TCP不丢包这个我懂,我怀疑是Server来不及接收,缓冲区出问题了。
这种极端的情况,不是普通的理论能说明问题的,需要实际的尝试和经验,以及深层次的技术理解。***********************************************
补充说明,
1)我这个应用场景,不会有很多的Socket客户端,10多个,几十个最多了。但是每个客户端发送数据的频率可能极快,而且可能会持续一小段时间。
2)我的socket,server端和client端做没做异步设置,情况都一样。
只要放到一个10万大小的一个数组里即可,每次收到一个id,就把对应的位置标记一下。
服务器判断数组内容有重复的时候,就是出错了。判断数组已经满了,就是接受成功了。
如果服务器是多线程,注意一下同步数据的问题。
其实我最开始也没有把每条消息都显示到console上,而是简单的统计收到的数量,就是发现数量不正确,才把消息显示出来的。
send这边,我还真没有很严格每次去做检查,只是判断返回值“正常”就计数加1,这样下来最后10个子进程都是成功发送10000。这个问题下周一再完善一下。
现在主要是我还不是特别精通Socket 接口函数,和内核在收发数据时的内部过程,所以无法判断问题根源。
短时间去整这个也来不及。
所以很想听听大家有没有遇到过类似的情况。对了,我还要补充一个调试测试时发现的重要现象:
如果不是多个客户端,只有一个客户端(也就是说我的应用中只有1个子进程),再怎么快的发送数据(不要Sleep),服务端也能全部正确接收。
我想,从Server的接收频率来说,1个客户端不Sleep的发送,频率应该比10的客户端Sleep(1)的间隔发送的频率要高。
那为什么1个客户端的时候Server就正确了呢。
我感觉这个问题还是有点价值的,
也希望大家能一起讨论一下,相互学习。
也想过用完成端口来试试,但是暂时不想去折腾那个。
底层的TCP传送是不会存在问题的, 更何况是单机