我写了一个服务器/客户端程序。并使用select
检查套接字。但是当客户端关闭套接字(服务器中的tcp状态将获得close_wait
)时,请选择始终返回1,并且errno为0.当tcp在close_wait时,选择总是返回1
为什么select
返回1? Tcp socket现在没有什么可读的!
服务器:
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(6999);
socklen_t socklen = sizeof(struct sockaddr_in);
bind(sock, (struct sockaddr *)&addr, socklen);
listen(sock, 0);
int clisock;
clisock = accept(sock, NULL, NULL);
fd_set backset, rcvset;
struct timeval timeout;
timeout.tv_sec = 3;
int maxfd = clisock+1;
FD_SET(clisock, &rcvset);
backset = rcvset;
int ret;
while(1) {
rcvset = backset;
timeout.tv_sec = 3;
ret = select(maxfd, &rcvset, NULL, NULL, &timeout);
if(ret <= 0)
continue;
sleep(1);
printf("ret:%d, %s\n",
ret, strerror(errno));
}
客户端:
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(6999);
socklen_t socklen = sizeof(struct sockaddr_in);
connect(sock, (struct sockaddr *)&addr, socklen);
sleep(3);
close(sock);
sleep(100);
输出:
./server
ret:1, Success
ret:1, Success
ret:1, Success
当远程端点关闭其连接时,本地端点将变为可读,但是'read'返回'0'。这表示远程终点已经关闭,'read'返回'0'。 – 2014-09-03 08:21:14
关于你使用'errno',不要检查它,除非实际上*是一个错误,并且在错误的函数调用之后总是直接检查它(即如果'select'失败,你必须直接检查'errno'' select')。想一想,如果“睡眠”失败会发生什么?然后'errno'将包含'sleep'函数的错误。 – 2014-09-03 08:23:25
循环速度如此之快,所以我添加了一个睡眠。 errno总是0.谢谢! – 2014-09-03 08:26:41