【问题标题】:Determine the state of a TCP socket确定 TCP 套接字的状态
【发布时间】:2014-01-31 14:26:25
【问题描述】:

我开始学习如何在 C++ 中实现 TCP 服务器/客户端(在 Windows 和 Linux 上)。 此时,我正在实现服务器(并使用 telnet 作为客户端进行测试)。 服务器应用程序像魅力一样发送和接收数据..(我将在了解所有服务器端后实现客户端)。 但我需要找到一种编程(C++ 或 OS API)的方式来查询 TCP 套接字状态(ESTABLISHED、FIN_WAIT_2、CLOSE_WAIT 等),而不使用 write()/recv() 来处理错误异常..

例如:

  1. 服务器启动,绑定套接字并等待连接
  2. 客户端启动并连接到服务器
  3. 这里,我在服务器上有一个循环,它使用函数“ioctlsocket(socket, FIONREAD, pbytes_available)”来确定我何时有数据要读取..
  4. 如果客户端发送一些数据,那么“pbytes_available”将> 1,服务器使用recv()获取。
  5. 如果客户端没有发送任何内容,那么服务器可以执行其他任务,并在下一个循环中检查套接字上是否有数据。
  6. 如果我关闭 TELNET(客户端进程)并运行“netstat”,我会看到服务器套接字处于“CLOSE_WAIT”状态,所以我需要关闭服务器端的套接字..李>

这就是问题:如何查询 TCP 套接字状态以确定我需要关闭此会话? (不使用 send()/recv(),就像“netstat”一样)

注意:我尝试了“getsockopt(socket, SOL_SOCKET, SO_ERROR, &optval, &optlen)”,但是当状态为 ESTABLISHED/CLOSE_WAIT 并且“optval”也没有时返回 0变化。

【问题讨论】:

  • 您想使用 select() 来查找要读取的数据和异常。请注意,并非所有操作系统都会告诉您套接字进程的另一端何时消失。
  • 我想要的是获取状态(例如:CLOSE_WAIT),就像 NETSTAT 可以做的那样......
  • 通常的 BSD 套接字 API 不会公开该信息。 Netstat 必须使用某些特定于操作系统的方式来获取信息。
  • 您将套接字的状态与端口的状态混淆了。套接字绑定或未绑定,连接或未连接。当它被连接时,它也被绑定。连接是打开还是半关闭或关闭是完全不同的事情。

标签: c++ api tcp network-programming


【解决方案1】:

阻塞模式套接字的常用技术是指定一个线程来读取套接字。当recv() 返回 0 时,表示对端已关闭连接,端口现在处于CLOSE_WAIT 状态。

或者,您可以使用select() 和朋友告诉您套接字何时可读,其中包括recv() 将返回零的情况。使用FIONREAD 作为轮询机制真的很没用,因为它没有涵盖这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2018-08-01
    • 2014-09-01
    • 2011-01-31
    • 2017-03-08
    • 2012-02-10
    • 2010-09-26
    相关资源
    最近更新 更多