当插座断开连接时如何判断?

时间:2010-06-22 03:49:04

标签: c# .net sockets

我正在使用C#的ElSSLSocket。这是一个SecureBlackBox套接字。 SecureBlackBox是处理安全套接字的第三方库。

我可以看到ElSSLSocket对象有一个名为'Socket'的属性,因此底层套接字是一个普通的.NET套接字。

我的问题是,是否存在某种我可以订阅的事件,以便我可以看到套接字何时断开连接?我有一个客户端服务器连接,经常会断开连接。很难看出它是客户端还是服务器,很难看出实际原因。

我很确定应用程序中存在一些逻辑问题,即这不是由网络中断或类似情况引起的。

我还应该告诉您,我得到的断开是这个错误,

SocketException - 远程主机强行关闭现有连接

ErrorCode - 10054

如果有任何方法可以找到原因吗?

3 个答案:

答案 0 :(得分:4)

检测半开连接是classic socket programming scenarios之一。 Socket.Connected属性完全没用,Socket.Poll不适用于所有情况。最好每隔几秒发送一次“心跳”消息。

10054是common errors之一。这意味着连接已丢失(未完全关闭)。它可能是由远程计算机关闭,远程进程退出,甚至中间路由器重新启动引起的。

答案 1 :(得分:2)

虽然这是用C写的,但您应该可以在C#中执行相同的操作:

int dummy;
// since you're just testing if the socket is still open for reading you don't
// want it to block, or remove data from the sockets recv buffer
int ret = recv(sockfd, &dummy, sizeof dummy, MSG_DONTWAIT | MSG_PEEK);

if ( ( ret == -1 && ( errno == EAGAIN || errno == EWOULDBLOCK ) )
      || ret > 0 ) {

    // socket is still open for reading

else if ( ret == 0 ) { 

    // socket went through orderly shutdown and is closed for reading

} else {

    // there is some error and the socket is likely closed
    // check errno

}

假设您认为它已关闭一半,您仍然有想要写的数据。

int myData = 0xDEADBEEF;
int ret = send(sockfd, myData, sizeof myData, MSG_NOSIGNAL);

这样,如果套接字完全关闭,您的发送不会使用SIGPIPE来终止您的程序。相反,调用只返回-1并将errno设置为EPIPE

答案 2 :(得分:1)

我发现这很有效:

<强>接收

_socket.Poll(100, SelectMode.SelectRead) && _socket.Available == 0

<强>发送

!_socket.Poll(100, SelectMode.SelectWrite)