【问题标题】:TCP socket continuously returns EAGAINTCP 套接字不断返回 EAGAIN
【发布时间】:2014-06-02 13:15:18
【问题描述】:

在我的测试中,我发现当我从发送方发送 1000-5000 字节的数据包时,它们会在接收方组装/捆绑,大小为 8000-14000 字节。我检查了wireshark捕获来确认这一点。

我有两个问题: 1) 谁将这些数据包捆绑在一起,接收者接收这些数据包,我使用 select() 来检测数据并调用 recvmsg api?。

2) 当接收方的数据包长度增加时,我实现了部分接收,因此“recvmsg”也返回部分数据。在这种情况下,一段时间后,recvmsg 调用返回 EAGAIN 0 字节。 与peer的连接还在,因为peer还在发送数据包,为什么recvmsg call returing error with EAGAIN ?.

请帮忙!

【问题讨论】:

  • 您必须处于非阻塞模式。解决办法:d不可以,或者使用select()。
  • 我已经使用 select() 来获取数据通知。我的接收器能够接收数据一段时间,但是随着大字节的到来,recvmsg 调用返回 o 字节。
  • 如果 select() 指示通道是可读的,则永远不应该这样做。你的描述没有意义。如果 recv() 返回 -1 并将 errno 设置为 EAGAIN 它不会同时给你零字节。它不能返回零 -1。如果您获得 EAGAIN,则仅表示没有可阅读的内容,您必须重新选择。
  • 谢谢..但我很确定在高负载期间会发生此问题。是的,它返回 0 个字节,但套接字缓冲区仍有数据。我使用 ioctl 来跟踪 recv 缓冲区中的数据并调用它返回 EAGAIN 的 recvmsg .. 如果 recv 缓冲区中的消息大小超过某个限制然后这个问题出现//
  • 只有当 recv 缓冲区中的数据增加一些限制时,我才会得到 EAGAIN,我猜它在 32767 左右。正如我所说,我使用 ioctl 来计算 recv 缓冲区大小,然后使用返回 EAGAIN 的“recvmsg”帮助。这发生在高负载..对于小数据包流工作正常/

标签: tcp recv


【解决方案1】:

我发现,当我从发送方发送 1000-5000 字节的数据包时,它们会在接收方组装/捆绑,大小为 8000-14000 字节

1) 谁在中间捆绑这些数据包,接收者接收这些数据包,我使用 select() 检测数据并调用 recvmsg api?。

如果这些是大小为 9000 字节的以太网数据包,那么您必须使用 jumbo frames

TCP 是一个流,没有消息的概念。在多个send() 调用中发送的数据可能会在一个recv() 调用中接收,反之亦然。

2) 当接收方的数据包长度增加时,我实现了部分接收,因此“recvmsg”也返回部分数据。在这种情况下,一段时间后,recvmsg 调用返回 EAGAIN 0 字节。与peer的连接还在,因为peer还在发送数据包,为什么recvmsg call returing error with EAGAIN ?.

这意味着您正在使用非阻塞套接字,并且套接字接收缓冲区中没有更多数据可用。在这种情况下,您应该使用select/poll/epoll 等待一个或多个套接字,直到有更多数据可供读取。

【讨论】:

  • 我在接收器套接字上有可用的数据,因为我使用 ioctl 调用来检查 recv 套接字缓冲区中的数据长度。选择返回要求我从此套接字读取,然后当我读取它时,recvmsg 返回 EAGAIN。这适用于小数据包,但是当 recv 缓冲区的长度增加一些限制时,我会遇到这个问题。
猜你喜欢
  • 2016-08-01
  • 2010-10-18
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
相关资源
最近更新 更多