如何在C语言中判断socket是否已经断开
下面来介绍判断非阻塞SOCKET是否已经断开的几种方法:
注意要区分不同操作系统分别进行测试,包括WINDOWS,LINUX和UNIX会各有不同。
在WINDOWS下比较简单,可以使用FD_CLOSE事件判断SOCKET是否已经断开
viewplaincopytoclipboardprint? boolIsSocketClosed(SOCKETclientSocket) { boolret=false; HANDLEcloseEvent=WSACreateEvent(); WSAEventSelect(clientSocket,closeEvent,FD_CLOSE); DWORDdwRet=WaitForSingleObject(closeEvent,0); if(dwRet==WSA_WAIT_EVENT_0) ret=true; elseif(dwRet==WSA_WAIT_TIMEOUT) ret=false; WSACloseEvent(closeEvent); returnret; }
在UNIX/LINUX下,非阻塞模式SOCKET可以采用recv+MSG_PEEK的方式进行判断,其中MSG_PEEK保证了仅仅进行状态判断,而不影响数据接收
对于主动关闭的SOCKET,recv返回-1,而且errno被置为9(#defineEBADF 9/*Badfilenumber*/)
或104(#defineECONNRESET104/*Connectionresetbypeer*/)
对于被动关闭的SOCKET,recv返回0,而且errno被置为11(#defineEWOULDBLOCKEAGAIN/*Operationwouldblock*/)
对正常的SOCKET,如果有接收数据,则返回>0,否则返回-1,而且errno被置为11(#defineEWOULDBLOCKEAGAIN/*Operationwouldblock*/)
因此对于简单的状态判断(不过多考虑异常情况),
recv返回>0, 正常
返回-1,而且errno被置为11 正常
其它情况 关闭
viewplaincopytoclipboardprint? #includeboolIsSocketClosed(intclientSocket) { charbuff[32]; intrecvBytes=recv(clientSocket,buff,sizeof(buff),MSG_PEEK); intsockErr=errno; //cout<<"Inclosefunction,recv"< 0)//Getdata returnfalse; if((recvBytes==-1)&&(sockErr==EWOULDBLOCK))//Noreceivedata returnfalse; returntrue; }
此外,所有操作系统上还可以通过TCP_KEEPLIVE实行心跳检测。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。