Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 在UDP套接字上执行操作时,是什么导致sendto()发送的字节数少于请求的字节数?_Sockets_Udp_Sendto_Mtu - Fatal编程技术网

Sockets 在UDP套接字上执行操作时,是什么导致sendto()发送的字节数少于请求的字节数?

Sockets 在UDP套接字上执行操作时,是什么导致sendto()发送的字节数少于请求的字节数?,sockets,udp,sendto,mtu,Sockets,Udp,Sendto,Mtu,在UDP套接字上执行操作时,什么会导致sendto()发送的字节数少于请求的字节数 问这个问题的动机是想找出我需要采取的预防措施,以确保我总是在对sendto()的一次调用中获得一条完整的消息,并了解我需要采取哪些进一步的步骤才能将消息获取到一个IP数据包中。我是否只需要确保我的邮件小于某个大小,如果是,大小是多少?除了操作系统特定的UDP数据报大小限制和MTU外,是否还有其他因素在起作用(例如i/o缓冲区容量、反复无常的操作系统) 在提出了上面的主要问题之后,在这篇文章的标题中,我将继续回答一

在UDP套接字上执行操作时,什么会导致
sendto()
发送的字节数少于请求的字节数

问这个问题的动机是想找出我需要采取的预防措施,以确保我总是在对
sendto()
的一次调用中获得一条完整的消息,并了解我需要采取哪些进一步的步骤才能将消息获取到一个IP数据包中。我是否只需要确保我的邮件小于某个大小,如果是,大小是多少?除了操作系统特定的UDP数据报大小限制和MTU外,是否还有其他因素在起作用(例如i/o缓冲区容量、反复无常的操作系统)

在提出了上面的主要问题之后,在这篇文章的标题中,我将继续回答一些相关的后续问题,然后在文章的最后将问题放在上下文中

其他问题

更详细地讲,再次假设我们是在UDP套接字上操作:

  • 是否每次成功调用
    sendto()
    都会导致只发送1个UDP数据报?(我理解这可能会分割成多个IP数据包)

  • 每次成功调用
    recvfrom()
    是否会准确检索到1个UDP数据报

  • 如果一条消息需要N次调用
    sendto()?(我知道数据报的顺序是不可预测的)

  • 假设我尝试发送一条消息,其大小等于或小于本地和远程系统支持的最大UDP数据报大小中的较小者(并且出现一些错误,这将导致返回值为-1),
    sendto()
    是否保证一次发送完整条消息?或者它可能会报告发送的字节数比我要求的要少?若然,原因为何?回到问题1

  • 除了问题4中的假设之外,假设我的消息不大于(MTU-UDP报头-IP报头)的大小,那么得到的UDP数据报是否保证适合1个IP数据包(至少在我的本地网络上)

  • 上下文

    我刚刚开始编写我的第一个基于UDP的通信协议(跨平台:例如linux、mac、windows、ios、android等)。我是一名套接字新手,但我知道使用UDP等简单协议会带来“成本”,并研究了以下算法/策略:

    • 将大消息拆分为多个小消息
    • 帮助补偿某些数据包丢失(通过减少重发请求)
    • 加密(见http://srp.stanford.edu/)
    我试图将所有通信分解为原子消息(即单个、自包含的UDP数据报),这些消息可能(但不一定)需要放入单个IP数据包(例如1500字节)。吞吐量和数据包丢失的实时评估将确定是否必须收缩数据报以适应单个IP数据包(这将导致额外报头的大小损失)。其中一些将通过wifi/无线链路实现,因此我希望能够自适应地确定“最佳”数据报大小。我知道我所有接口的MTU,并且理解在我的本地网络之外,数据包可能会被进一步分割,但这是我无法控制的,所以我可以接受它


    但一切都取决于能否构造一条原子消息,并且我有100%的信心,只要调用
    sendto()
    ,就可以成功地发送它,只要调用
    recvfrom()
    ,就可以接收if。我所有的应用程序级可靠性、拆分、编码和加密信息都保存在我自己的协议头中,在调用
    sendto()
    后,我无法重新拆分消息。例如,设想一条消息校验和:如果整条消息不能一次性通过,则报头中的校验和对于已发送的消息部分不再有效。

    我有许多协议的经验,这些协议都做出了这样一个精确的基本假设,即发送的任何UDP数据包都将在一次呼叫中发送,并在一次呼叫中接收(或者根本没有)。在应用程序级别上看不到由于MTU等产生的任何碎片。许多实时流协议限制数据包大小以限制碎片造成的延迟,但这一切都是秘密的。只需确保接收缓冲区足够大即可

    一切都取决于能否构造一条原子消息,并且我有100%的信心通过对sendto()的一次调用成功地发送它,通过对recvfrom()的一次调用成功地接收if

    UDP保证。数据报完好无损地到达,或者根本不到达。您所需要的只是确保套接字发送和接收缓冲区足够大,并且如果您正在穿越路由器,则每个数据报发送的字节数不超过534字节:这是普遍接受的限制