C语言 如何在C中找到套接字连接状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4142012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find the socket connection state in C?
提问by Blacklabel
I have a TCP connection. Server just reads data from the client. Now, if the connection is lost, the client will get an error while writing the data to the pipe (broken pipe), but the server still listens on that pipe. Is there any way I can find if the connection is UP or NOT?
我有一个 TCP 连接。服务器只是从客户端读取数据。现在,如果连接丢失,客户端将在将数据写入管道(损坏的管道)时出错,但服务器仍然在该管道上侦听。有什么办法可以找到连接是否正常?
回答by Simone
You could call getsockopt just like the following:
你可以像下面这样调用getsockopt:
int error = 0;
socklen_t len = sizeof (error);
int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len);
To test if the socket is up:
要测试套接字是否已启动:
if (retval != 0) {
/* there was a problem getting the error code */
fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
return;
}
if (error != 0) {
/* socket has a non zero error status */
fprintf(stderr, "socket error: %s\n", strerror(error));
}
回答by Chris Becke
The only way to reliably detect if a socket is still connected is to periodically try to send data. Its usually more convenient to define an application level 'ping' packet that the clients ignore, but if the protocol is already specced out without such a capability you should be able to configure tcp sockets to do this by setting the SO_KEEPALIVEsocket option. I've linked to the winsock documentation, but the same functionality should be available on all BSD-like socket stacks.
可靠地检测套接字是否仍然连接的唯一方法是定期尝试发送数据。定义客户端忽略的应用程序级别的“ping”数据包通常更方便,但是如果协议已经指定而没有这样的功能,您应该能够通过设置SO_KEEPALIVE套接字选项来配置 tcp 套接字来执行此操作。我已经链接到 winsock 文档,但是所有类似 BSD 的套接字堆栈都应该提供相同的功能。
回答by blaze
TCP keepalive socket option (SO_KEEPALIVE) would help in this scenario and close server socket in case of connection loss.
TCP keepalive 套接字选项 (SO_KEEPALIVE) 在这种情况下会有所帮助,并在连接丢失的情况下关闭服务器套接字。
回答by Parth Shah
I had a similar problem. I wanted to know whether the server is connected to client or the client is connected to server. In such circumstances the return value of the recv function can come in handy. If the socket is not connected it will return 0 bytes. Thus using this I broke the loop and did not have to use any extra threads of functions. You might also use this same if experts feel this is the correct method.
我有一个类似的问题。我想知道是服务器连接到客户端还是客户端连接到服务器。在这种情况下, recv 函数的返回值可以派上用场。如果套接字未连接,它将返回 0 字节。因此,使用它我打破了循环并且不必使用任何额外的函数线程。如果专家认为这是正确的方法,您也可以使用相同的方法。
回答by Tal Bar
You should try to use: getpeernamefunction.
您应该尝试使用:getpeername函数。
now when the connection is down you will get in errno: ENOTCONN - The socket is not connected. which means for you DOWN.
现在,当连接断开时,您将进入 errno:ENOTCONN - 套接字未连接。这对你来说意味着 DOWN。
else (if no other failures) there the return code will 0 --> which means UP.
否则(如果没有其他失败)返回代码将为 0 --> 表示 UP。
resources:man page: http://man7.org/linux/man-pages/man2/getpeername.2.html
资源:手册页:http: //man7.org/linux/man-pages/man2/getpeername.2.html
回答by chandank
get sock opt may be somewhat useful, however, another way would to have a signal handler installed for SIGPIPE. Basically whenever you the socket connection breaks, the kernel will send a SIGPIPE signal to the process and then you can do the needful. But this still does not provide the solution for knowing the status of the connection. hope this helps.
get sock opt 可能有点用,但是,另一种方法是为 SIGPIPE 安装信号处理程序。基本上,每当您的套接字连接中断时,内核都会向进程发送一个 SIGPIPE 信号,然后您就可以执行所需的操作了。但这仍然没有提供了解连接状态的解决方案。希望这可以帮助。
回答by yanpas
There is an easy way to check socket connection state via pollcall. First, you need to poll socket, whether it has POLLINevent.
有一种通过poll调用检查套接字连接状态的简单方法。首先,你需要轮询socket,它是否有POLLIN事件。
- If socket is not closed and there is data to read then
readwill return more than zero. - If there is no new data on socket, then
POLLINwill be set to 0 inrevents - If socket is closed then
POLLINflag will be set to one and read will return 0.
- 如果套接字未关闭并且有数据要读取,
read则将返回多于零。 - 如果socket上没有新数据,则
POLLIN在revents - 如果套接字关闭,则
POLLIN标志将设置为 1,读取将返回 0。
Here is small code snippet:
这是小代码片段:
int client_socket_1, client_socket_2;
if ((client_socket_1 = accept(listen_socket, NULL, NULL)) < 0)
{
perror("Unable to accept s1");
abort();
}
if ((client_socket_2 = accept(listen_socket, NULL, NULL)) < 0)
{
perror("Unable to accept s2");
abort();
}
pollfd pfd[]={{client_socket_1,POLLIN,0},{client_socket_2,POLLIN,0}};
char sock_buf[1024];
while (true)
{
poll(pfd,2,5);
if (pfd[0].revents & POLLIN)
{
int sock_readden = read(client_socket_1, sock_buf, sizeof(sock_buf));
if (sock_readden == 0)
break;
if (sock_readden > 0)
write(client_socket_2, sock_buf, sock_readden);
}
if (pfd[1].revents & POLLIN)
{
int sock_readden = read(client_socket_2, sock_buf, sizeof(sock_buf));
if (sock_readden == 0)
break;
if (sock_readden > 0)
write(client_socket_1, sock_buf, sock_readden);
}
}
回答by bem22
Very simple, as pictured in the recv.
非常简单,如recv 中所示。
To check that you will want to read 1 byte from the socket with MSG_PEEKand MSG_DONT_WAIT. This will not dequeue data (PEEK) and the operation is nonblocking (DONT_WAIT)
要检查您是否要使用MSG_PEEK和从套接字读取 1 个字节MSG_DONT_WAIT。这不会使数据出列 ( PEEK) 并且操作是非阻塞的 ( DONT_WAIT)
while (recv(client->socket,NULL,1, MSG_PEEK | MSG_DONTWAIT) != 0) {
sleep(rand() % 2); // Sleep for a bit to avoid spam
fflush(stdin);
printf("I am alive: %d\n", socket);
}
// When the client has disconnected, this line will execute
printf("Client %d went away :(\n", client->socket);
Found the example here.
在这里找到了这个例子。
回答by smallscript
On Windows you can query the precise state of any port on any network-adapter using: GetExtendedTcpTable
在 Windows 上,您可以使用以下命令查询任何网络适配器上任何端口的精确状态: GetExtendedTcpTable
You can filter it to only those related to your process, etc and do as you wish periodically monitoring as needed. This is "an alternative" approach.
您可以将其过滤为仅与您的流程等相关的内容,并根据需要定期监控。这是“替代”方法。
You could also duplicate the socket handle and set up an IOCP/Overlapped i/o wait on the socket and monitor it that way as well.
您还可以复制套接字句柄并在套接字上设置 IOCP/Overlapped i/o 等待并以这种方式监视它。
回答by pankaj kushwaha
you can use SS_ISCONNECTEDmacro in getsockopt()function.
SS_ISCONNECTEDis define in socketvar.h.
您可以SS_ISCONNECTED在getsockopt()函数中使用宏。
SS_ISCONNECTED在 中定义socketvar.h。

