我正在使用C#的ElSSLSocket。这是一个SecureBlackBox套接字。 SecureBlackBox是处理安全套接字的第三方库。
我可以看到ElSSLSocket对象有一个名为'Socket'的属性,因此底层套接字是一个普通的.NET套接字。
我的问题是,是否存在某种我可以订阅的事件,以便我可以看到套接字何时断开连接?我有一个客户端服务器连接,经常会断开连接。很难看出它是客户端还是服务器,很难看出实际原因。
我很确定应用程序中存在一些逻辑问题,即这不是由网络中断或类似情况引起的。
我还应该告诉您,我得到的断开是这个错误,
SocketException - 远程主机强行关闭现有连接
ErrorCode - 10054
如果有任何方法可以找到原因吗?
答案 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)