首页 > 开发 > linux > 正文

linux网络编程中如何判断服务器或者客户端已经关闭?

2017-09-11 20:33:44  来源: 网友分享

是这样的,开了个服务器,开了个客户端连上,正常通信,客户端可以给服务器发数据。
这时候,关闭了服务器,然后客户端继续发数据并不会马上出错,可是再发一次客户端程序便自动退出了。
请问,为什么呢?
还有就是如果是客户端关闭,服务器往客户端发数据会不会出现这种情况?
(如果上面第二个问题答案是ture的话)怎么解决?(一个服务器不可能因为一个客户端的关闭而退出吧?)

#include <stdio.h>#include <unistd.h>#include <sys/socket.h>#include <pthread.h>#include <arpa/inet.h>#include <errno.h>#include <sys/types.h>#include <stdlib.h>#include <memory.h>#define MAX 4096int main(int argc, char **argv){    int clientfd;    if((clientfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){        printf("Error:%s\n", strerror(errno));	exit(0);    }    struct sockaddr_in myaddr;    memset(&myaddr, '0', sizeof(myaddr));    myaddr.sin_family = AF_INET;    myaddr.sin_port = htons(4444);    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);    if( connect(clientfd, (struct sockaddr*)&myaddr, sizeof(myaddr)) < 0){        printf("connect error: %s(errno: %d)\n",strerror(errno),errno);	exit(0);    }	    char sendline[MAX];    while(1){        printf("send msg to server: \n");	fgets(sendline, 4096, stdin);	if(send(clientfd, sendline, strlen(sendline), 0) <= 0)	{	    printf("send msg error: %s(errno: %d)", strerror(errno), errno);	    exit(0);	}    }    close(clientfd);    exit(0);    return 1;}

解决方案

如果在正常通信中,服务器关闭了连接那么客户端会收到正常的EOF,如果对这个连接用epoll或者select进行监听,可以马上得知服务器关闭了连接。否则就定时向服务器发心跳探测,不然是不太可能得知服务器目前的状态的。之所以你现在不会立刻发现问题是因为服务器退出后,客户端需要靠下一次send才会触发问题,因为这时候连接已关闭,而客户端继续写,会产生SIGPIPE异常,而这个异常的默认动作是进程终止,所以你的客户端退出了。vice versa.