确定 TCP 套接字的状态 [英] Determine the state of a TCP socket

查看:29
本文介绍了确定 TCP 套接字的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习如何在 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"状态,因此我需要关闭服务器端的套接字..
  7. 立>

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

注意:我尝试了getsockopt(socket, SOL_SOCKET, SO_ERROR, &optval, &optlen)",但是当状态为 ESTABLISHED/CLOSE_WAIT 和optval"时它返回 0也不会改变.

解决方案

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

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

I'm starting to learn about how to implement in C++ a TCP server/client (on Windows and Linux). At this moment, I'm implementing the server (and testing with the telnet as client). The server application is sending and recieving data like a charm.. (I will implement the client after understand all the server side). But I need to find a programmatic (C++ or O.S API) way to query the TCP socket state (ESTABLISHED, FIN_WAIT_2, CLOSE_WAIT, etc..) without use the write()/recv() to handle the error exception..

For example:

  1. Server starts, bind the socket and wait a connection
  2. A client starts and connect on the server
  3. Here, I have a loop at the server that use the func "ioctlsocket(socket, FIONREAD, pbytes_available)" to determine when I have data to read..
  4. If the client send some data, then "pbytes_available" will be > 1 and the server use recv() to get.
  5. If the client doesn't sends anything, then the server can do other tasks and check if there are data on the socket at the next loop.
  6. If I close the TELNET (client process) and run the "netstat", I'll see that the server socket is with the "CLOSE_WAIT" state, so I need to close the socket at the server side..

And this is the question: How can I query the TCP socket state to determine that I need close this session? (without use the send()/recv(), like the "netstat" do)

Note: I tried the "getsockopt(socket, SOL_SOCKET, SO_ERROR, &optval, &optlen )", but it return 0 when the state is ESTABLISHED/CLOSE_WAIT and the "optval" also doesn't changes.

解决方案

The usual technique with blocking-mode sockets is to dedicate a thread to reading the socket. When recv() returns 0 it means the peer has closed the connection and the port is now in CLOSE_WAIT state.

Alternatively you can use select() and friends to tell you when the socket is readable, which includes the case where recv() will return zero. Using FIONREAD as a polling mechanism is really pretty useless as it doesn't cover this case.

这篇关于确定 TCP 套接字的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆