ARM上基于Linux编写的 TCP 服务器,当客户端断开连接时,使用 select 函数的情况下,服务器仍然会接收到一个信号,在 select 函数会将这个设备描述符标记为可读/写,然后调用 recv 函数,若 recv 函数返回值为 0,则表示客户端已经断开,服务器需要将对应的 Socket 套接字关闭掉,让数据写回磁盘,并释放文件所占用的资源。
第一步
判断多路接入的客户端对否有处于可读/写状态的设备,若客户端断开,也会触发可读/写状态。
selectNum = select(fdmax + 1, &fdr, NULL, NULL, &SelectTimeOut);
第二步
判断是否 fdr 集合中的设备触发 select 函数返回,再判断 recv 的返回值,如果 ret 大于 0 ,则正常接收到数据;如果 ret 等于 0 ,则表示客户端异常(断开),需要关闭相应的套接字;如果 ret 小于 0,则表示接收出错。
if (FD_ISSET(client[i], &fdr))
{
ret = recv(client[i], buf, sizeof(buf), 0);
if (ret > 0)
{
printf("client%d receive: %s %d\n", i + 1, buf, ret);
}
else if (ret == 0)
{
if (close(client[i]) >= 0)
{
printf("close socket success cfd=%d \n", client[i]);
FD_CLR(client[i], &fdr);
//后续其他处理
}
}
else
{
perror("recv");
exit(-1);
}
}
总结
通过 select 函数判断之后,再判断 recv 函数的返回值是否为 0,可以判断客户端是否已经断开。