【问题标题】:tcp/ip accept not returning, but client doestcp/ip 接受不返回,但客户端返回
【发布时间】:2010-06-09 03:55:18
【问题描述】:

服务器:
vxworks 6.3
调用通常的socket,绑定,监听,然后:

for (;;)
{
  client = accept(sfd,NULL,NULL);
  // pass client to worker thread
}

客户:
.NET 2.0
TcpClient 构造函数连接到接受字符串主机名和 int 端口的服务器,例如:

TcpClient client = new TcpClient(server_ip, port);

当服务器在 windows (native c++) 中编译和执行时,这可以正常工作。

TcpClient 的构造函数会间歇性地返回实例,不会抛出任何异常,但 vxWorks 中的 accept 调用不会随客户端 fd 返回。 tcpstatShow 表示没有接受。

什么可能使 TcpClient 构造函数(调用“连接”)返回实例,而服务器上的接受调用不返回?它似乎与系统在后台执行的操作有关 - 当服务器忙于将数据持久保存到闪存或客户端尝试连接时的 NFS 共享时,似乎更有可能出现此症状,但当它发生时可能会发生也不是。

我已尝试调整运行接受线程的优先级
我在“听”中查看了队列的大小。够了。
可用的文件描述符总数应该足够了(虽然还没有验证这一点,早上第一件事)

【问题讨论】:

  • 你弄清楚这里发生了什么吗?
  • 不。 - 我有一个与 WindRiver(vxworks) 相关的支持请求。我做了wireshark跟踪,当它发生时,我看到了正确的SYN和SYN,ACK,所以windows做了正确的事情。不过,它从未在我们部署的目标上发生过,这可能是侥幸,这就是为什么我们已经使用它这么长时间了……之前的 IP 帧是之前数据流上的 RST、ACK - 也​​许这就是问题所在,在 vxworks 方面...端口 > 1000
  • 当你使用无参数构造函数然后调用 Connect(addr, port)。有用吗?

标签: c# .net c#-2.0 tcp vxworks


【解决方案1】:

您是否可以发布有关网络上正在发生的事情的wireshark/netmon?

【讨论】:

  • 第二。这将隔离问题是在客户端还是服务器端,将要查看的位置数量减半。不过,这应该是评论而不是答案吗?
  • 第三次。 Wireshark 将是非常有用的反馈
  • 这看起来像我要走的路......不想,希望有人会提到类似 - '哦,TcpClient 不适用于 vxWorks,你有你得到里面的 Socket 并设置标志 xyz 或其他东西'......哦,好吧。
  • 清理不被接受的答案 - 这是最接近的,因为它有助于调查。问题是 vxWorks 中的 netStackSysPool 不够大。
【解决方案2】:

这可能有很多原因,但除非我们能从服务器和客户端获得更多信息,否则我们不会知道。它会抛出任何错误吗?可以在此处找到 TCP/IP 错误列表Windows Socket Error. 在服务器端,您是否发现任何异常?也许您可以在出现错误后尝试关闭连接(逗留 1 秒)?

【讨论】:

  • 这正是问题所在——没有错误!客户端愉快地返回 TcpClient 实例,但服务器从不接受从返回。在服务器端,不会有例外,因为套接字库是 C 库,而不是 C++。我已经到了编写自己的协议的地步,以通过立即将数据发送回客户端来确认接受是否有效,如果在一段时间后我没有得到它,我会尝试再次连接...但那将是多么大的一团糟!
【解决方案3】:

是否可以将服务器绑定到另一个端口并查看它是否接受?如果客户端返回,它听起来像是从您的服务器上的某些东西那里得到了一个接受。 我不了解 vxworks,但在 Windows 中,您应该始终尝试不绑定到 1000 以下的任何内容。

【讨论】:

    【解决方案4】:

    您的服务器的accept() 调用看起来错误。我知道的 POSIX accept() 调用有:

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
    

    其中*addr 是一个必需的指针,如果调用有效,则写入该指针 — 实际上,调用的失败状态之一是:

    [EFAULT]    The address parameter is not in a writable part of the user address space.
    

    我没有做过 Windows 套接字编程,但我知道它是 POSIX 兼容的,而且 Beej 的指南没有提到 accept() 的任何 Windows 例外,所以这应该仍然适用。有点相关,Python 的 accept() 调用 also 'returns' the address field(我这么说是因为 Python 尽最大努力模拟 C 网络 API,因为它是有意义的。)

    我建议检查errno 并在服务器中调用accept 之后使用perror,以查看是否设置了[EFAULT](如果您的描述符用完,它也会通知您,如errno设置为[EMFILE][ENFILE])

    如果证明不是是问题所在,请使用ncat 作为服务器或客户端进行进一步调查。我会使用-vv 运行它,因为您想知道确切的连接时间、发送的内容等等。

    【讨论】:

    • 我使用的套接字不是 POSIX 合规性的一部分(它们不是 unix 域套接字),它们是互联网套接字或“BSD”套接字,它们不属于 POSIX。根据opengroup.org/onlinepubs/007908799/xns/accept.html,accept 的第二个参数是可选的。如果您不关心客户端的实际地址是什么,您可以传递 NULL。如果不允许,它仍然会返回一个错误,而我的却没有。
    猜你喜欢
    • 2020-08-27
    • 1970-01-01
    • 2021-07-19
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 2015-01-28
    相关资源
    最近更新 更多