Linux下作为TCP客户端发送数据时,偶尔会出现写操作成功,但数据似乎保留在发送缓冲区中,只有在接收超时后才发送出去的情况。这个结论是基于我使用 tcpdump 捕获数据包以及我在滞后期间收集的 SendQ 大小。关于套接字配置,当前设置为阻塞模式发送,并且启用了 NODELAY 标志。顺便说一句,服务器端是老式的SLIP设备。 数据卡在sendqueque中
我想知道可以用什么方法来解决这个问题。
下面是发送函数。
erpc_status_t TCPTransport::underlyingSend(const uint8_t *data, uint32_t size, void *arg)
{
int socket = (NULL == arg) ? m_socket : *(int *)arg;
if (socket < 0)
{
return kErpcStatus_InvalidArgument;
}
// Loop until all data is sent.
while (size)
{
#ifndef WIN32
ssize_t result = write(socket, data, size);
#else
int result = send_Data(socket, (char *)data, size, 0);
#endif
if (result >= 0)
{
size -= result;
data += result;
}
else
{
if (errno == EPIPE)
{
// Server closed.
//close();
TCP_DEBUG_ERR("underlyingSend() connect closed.");
return kErpcStatus_ConnectionClosed;
}
TCP_DEBUG_ERR("underlyingSend() send failed.");
return kErpcStatus_SendFailed;
}
}
return kErpcStatus_Success;
}
[erpc_tcp_transport.cpp][1] [1]:https://github.com/EmbeddedRPC/erpc/blob/develop/erpc_c/transports/erpc_tcp_transport.cpp
我必须添加一些细节。我对异常连接进行了通信测试。当系统中没有其他程序运行时,测试进行了2,000,000次通信尝试,没有任何异常。然而,当系统作为一个整体运行时,问题就会出现。因此,我仍然怀疑该问题可能是由于系统或网络繁忙引起的。我们也尝试捕获系统资源利用率,表明CPU和内存资源应该是充足的。
终于弄清楚了,Lockless qdisc有并发问题,这是linux 5.10的一个内核bug,下面是解决问题的链接。 [https://lkml.org/lkml/2021/5/13/1025][1]