情景相当简单......不允许使用" sendto()
"所以使用" send()
"代替...
在winsock2.2
下,在运行Windows 7 Professional
的全新i7机器上正常运行......
使用SOCK_DGRAM
套接字,客户端和服务器控制台应用程序通过localhost
(127.0.0.1
)进行连接以测试...
必须使用不变大小的数据包...
客户端套接字使用connect()
,服务器套接字使用bind()
...
客户端使用一系列BLOCKING
send()
次呼叫发送N个数据包。服务器仅使用ioctlsocket
与FIONREAD
进行调用,在while
循环中运行,以等待接收的printf()
字节数不断增加...
PACKETS丢失,除非我将SLEEP()
置于可考虑的时间内...... 我的意思是接收套接字上的字节数在运行之间有所不同,如果我这样做的话不要使用SLEEP()
...
玩过更改缓冲区大小,情况没有太大变化,除非现在没有溢出,但延迟问题仍然存在...
我已经看到很多关于send()
和recv()
之间问题的讨论,但在这种情况下,recv()
甚至没有参与......
有人想到吗?
(PS由于我无法控制的原因,我需要编程的约束,因此没有WSA
,.NET
,MFC
,STL
,{{1} },BOOST
或其他东西)
这不是缓冲区溢出的问题,原因有三个:
QT
,只通过recv()
调用检查传入缓冲区,在用户输入后很久就会调用recv()。 ioctl()
- s之间添加Sleep()
的{{1}}时,整个过程都有效,即如果出现溢出,则无法满足
>40ms
会有所帮助(send()
)答案 0 :(得分:0)
PACKETS失去了我,但我睡着了()有可观的数量 TIME ...我的意思是接收套接字上的字节数 如果我不使用SLEEP()......
,则运行之间会有所不同
这是预期的行为;正如其他人在评论中所说,UDP数据包可以并且确实因任何原因而被丢弃。但是,在仅使用localhost的通信环境中,原因通常是某个固定大小的数据包缓冲区已满,无法保留传入的UDP数据包。请注意,UDP没有流控制的概念,因此如果您的接收程序无法跟上您的发送程序,一旦缓冲区满了,肯定会发生数据包丢失。
关于如何处理,插入呼叫睡眠()解决方案并不是特别好,因为你没有好的方法知道"权利"睡眠持续时间应该是。 (要缩短睡眠时间(),你仍然会丢弃数据包;睡眠时间过长()并且你传输数据的速度比你原来要慢得多;当然还有#34;最佳&#34 ;值可能会因计算机而异,或者从一台计算机到下一个计算机,或者以一种非显而易见的方式发生。
您可以做的一件事是切换到不同的传输协议,例如TCP,或者(因为您只在localhost内进行通信),简单的管道或套接字对。这些协议具有您正在寻找的无损FIFO语义,因此它们可能是适合该工作的正确工具。
假设您需要使用UDP,但UDP丢包对您来说是事实,但您可以采取一些措施来减少数据包丢失:
请记住,无论您在减少UDP数据包丢失的机会方面多么聪明,UDP数据包丢失仍然会发生。因此,无论您需要设计哪种设计,即使数据包丢失,您的程序仍能以合理有用的方式运行。这可以通过实现某种自动重发机制来实现,或者(取决于你想要完成的工作)通过设计协议使得丢包可以简单地被忽略。