0
ioctl(socketFd_, SIOCOUTQ, &outstandingBytes);  
getsockopt(socketFd_, SOL_SOCKET, SO_SNDBUF, &sendBuffSize, &buffLen);  

我正在使用这两个 api 来调试程序中的丢包。
观察:

  1. sendto将始终返回数据包大小,因此调用sendto始终成功。
  2. oustandingBytes 达到 2040时,Linux 内核将丢弃数据包,这意味着我无法在 Wireshark 中看到它的数据包。我正在本地 eth 接口上捕获数据包。
  3. 我的sendBuffSize 是 124928,由getsockopt.
  4. 我发送的数据包大小约为 300 到 350 字节。我有两个套接字,一个用于发送 GRE 数据包的原始套接字和另一个 udp 套接字,我看到两种协议的数据包丢失,两个套接字都处于非阻塞模式。
    是否sendto无法检测到错误,因为数据包在达到 sendBuffSize 限制之前被丢弃?
    如何在我的系统中增加 2040 的限制。该值应为 api 返回的 124928 getsockopt()
    对于这个问题,我有类似的线程,如下所示,但是我无法得到答案,所以决定开始一个新线程。
    rawsocket sendto() 一些数据包被丢弃并且在网络中看不到
4

1 回答 1

0

UDP 和原始套接字不提供任何方法来检测丢弃的数据包。由于路由器故障或网络拥塞,数据包可能会在网络中丢失,也可能在内核中被丢弃。如果需要检测丢包,必须在应用层做,或者在UDP之上实现一个会话层。

如果内核在您调用时无法缓冲数据包sendto(),它应该返回-1并设置errnoEWOULDBLOCK.

于 2014-02-22T08:54:14.883 回答