gpt4 book ai didi

linux - Tru64 上的 sendto 正在返回 ENOBUF

转载 作者:太空狗 更新时间:2023-10-29 12:22:00 24 4
gpt4 key购买 nike

我目前在 Tru64 上运行一个旧系统,它涉及大量使用 sendto() 函数的 UDP 套接字。套接字在我们的代码中用于向/从各种进程发送消息,然后最终发送到远程连接的胖客户端应用程序。有时,胖客户端的套接字会卡住,这可能会导致其中一些消息堆积起来。我的问题是如何确定当前缓冲区大小,以及如何确定最大消息缓冲区。下面的代码给出了我如何设置端口和使用 sendto 函数的片段。

/* need to adjust the maximum size we can send on this */
/* as it needs to be able to cope with the biggest */
/* messages we send */

lenlen = sizeof(len) ;

/* allow double for when the system is under load */
int lenlen, len ;
lenlen = sizeof(len) ;
len = 2 * 32000;

msg_socket = socket( AF_UNIX,SOCK_DGRAM, 0);

result = setsockopt(msg_socket, SOL_SOCKET, SO_SNDBUF, (char *)&len, lenlen) ;

result = sendto( msg_socket,
(char *)message,
(int)message_len,
flags,
dest_addr,
addrlen);

注意。我们已将此应用程序移植到 Linux,问题似乎并未出现。

如有任何帮助,我们将不胜感激。

问候

最佳答案

UDP 发送缓冲区大小与 TCP 不同——它只是限制数据报的大小。引用史蒂文斯 UNP 卷。 1:

...A UDP socket has a send buffer size (which we can change with SO_SNDBUF socket option, Section 7.5), but this is simply an upper limit on the maximum-sized UDP datagram that can be written to the socket. If an application writes a datagram larger than the socket send buffer size, EMSGSIZE is returned. Since UDP is unreliable, it does not need to keep a copy of the application's data and does not need an actual send buffer. (The application data is normally copied into a kernel buffer of some form as it passes down the protocol stack, but this copy is discarded by the datalink layer after the data is transmitted.)
    UDP simply prepends 8-byte header and passes the datagram to IP. IPv4 or IPv6 prepends its header, determines the outgoing interface by performing the routing function, and then either adds the datagram to the datalink output queue (if it fits within the MTU) or fragments the datagram and adds each fragment to the datalink output queue. If a UDO application sends large datagrams (say 2,000-byte datagrams), there's a much higher probability of fragmentation than with TCP. because TCP breaks the application data into MSS-sized chunks, something that has no counterpart in UDP.
    The successful return from write to a UDP socket tells us that either the datagram or all fragments of the datagram have been added to the datalink output queue. If there is no room on the queue for the datagram or one of its fragments, ENOBUFS is often returned to the application.
     Unfortunately, some implementations do not return this error, giving the application no indication that the datagram was discarded without even being transmitted.

最后一个脚注需要注意 - 但看起来 Tru64 在 manual page 中列出了此错误代码.

不过,正确的做法是在应用程序本身中对未完成的消息进行排队,并在每次系统调用后仔细检查返回值和 errno。这仍然不能保证交付(因为 UDP 接收方可能会在没有通知发送方的情况下丢弃数据包)。使用 netstat -s 检查 UDP 数据包丢弃计数器在两侧/所有方面,看看它们是否在增长。除了切换到 TCP 或实现您自己的超时/确认和重新传输逻辑之外,真的没有办法解决这个问题。

关于linux - Tru64 上的 sendto 正在返回 ENOBUF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2809972/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com