如何在C中找到套接字连接状态?

我有一个TCP连接。 服务器只是从客户端读取数据。 现在,如果连接丢失,客户端将数据写入管道(断开的管道)时会出错,但服务器仍会侦听该管道。 如果连接是UP还是NOT,我有什么方法可以找到?

您可以像下面这样调用getsockopt:

int error = 0; socklen_t len = sizeof (error); int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len); 

要测试套接字是否已启动:

 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)); } 

可靠地检测套接字是否仍然连接的唯一方法是定期尝试发送数据。 通常更方便的是定义客户端忽略的应用程序级别“ping”数据包,但如果协议已经在没有这种function的情况下被推出,则应该能够通过设置SO_KEEPALIVE套接字选项来配置tcp套接字来实现此目的。 我已经链接到winsock文档,但是所有类似BSD的套接字堆栈都应该提供相同的function。

TCP keepalive套接字选项(SO_KEEPALIVE)将在此方案中提供帮助,并在连接丢失时关闭服务器套接字。

我有类似的问题。 我想知道服务器是连接到客户端还是客户端连接到服务器。 在这种情况下,recv函数的返回值可以派上用场。 如果套接字未连接,则返回0字节。 因此使用这个我打破了循环并且不必使用任何额外的函数线程。 如果专家认为这是正确的方法,您也可以使用相同的方法。

get sock opt可能有点用处,但是,另一种方法是为SIGPIPE安装一个信号处理程序。 基本上每当套接字连接中断时,内核都会向进程发送一个SIGPIPE信号,然后你就可以做到这一点。 但是,这仍然无法提供了解连接状态的解决方案。 希望这可以帮助。

您应该尝试使用: getpeername函数。

现在当连接断开时,你将进入errno:ENOTCONN – 套接字未连接。 这意味着你的DOWN。

否则(如果没有其他失败)返回代码将为0 – >这意味着UP。

资源:手册页: http : //man7.org/linux/man-pages/man2/getpeername.2.html

有一种通过poll调用检查套接字连接状态的简单方法。 首先,你需要轮询socket,它是否有POLLIN事件。

  1. 如果socket未关闭且有数据要读取,则read将返回大于零。
  2. 如果套接字上没有新数据,则在revents POLLIN将设置为0
  3. 如果socket已关闭,则POLLIN标志将设置为1,read将返回0。

这是一个小代码片段:

 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); } } 

你可以在getsockopt()函数中使用SS_ISCONNECTED宏。 SS_ISCONNECTEDsocketvar.h定义。

对于BSDsockets,我会查看Beej的指南 。 当recv返回0时,您知道另一侧已断开连接。

现在你可能真的在问,检测对方断开连接的最简单方法是什么? 一种方法是让一个线程总是做一个recv。 该线程将能够立即告知客户端何时断开连接。