如何检测客户端是否已与服务器断开连接?
我的AcceptCallBack
方法中有以下代码
static Socket handler = null;
public static void AcceptCallback(IAsyncResult ar)
{
//Accept incoming connection
Socket listener = (Socket)ar.AsyncState;
handler = listener.EndAccept(ar);
}
我需要找到一种方法来尽快发现客户端已从handler
套接字断开连接。
我试过了:
handler.Available;
handler.Send(new byte[1], 0, SocketFlags.None);
handler.Receive(new byte[1], 0, SocketFlags.None);
当您连接到服务器并想要检测服务器何时断开连接时,上述方法有效,但当您是服务器并想要检测客户端断开时,它们不起作用。
任何帮助都将不胜感激。
发布于 2009-04-06 16:46:23
由于没有事件可以在套接字断开连接时发出信号,因此您必须以您可以接受的频率轮询它。
使用此扩展方法,您可以有一个可靠的方法来检测套接字是否断开连接。
static class SocketExtensions
{
public static bool IsConnected(this Socket socket)
{
try
{
return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
}
catch (SocketException) { return false; }
}
}
发布于 2015-08-27 16:42:47
有人提到了TCP Socket的keepAlive功能。这里有一个很好的描述:
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
我是这样使用它的:连接套接字后,我调用此函数,该函数将keepAlive设置为on。keepAliveTime
参数指定在发送第一个保活数据包之前没有任何活动的超时时间(毫秒)。keepAliveInterval
参数指定在未收到确认的情况下连续发送保活数据包的时间间隔(毫秒)。
void SetKeepAlive(bool on, uint keepAliveTime, uint keepAliveInterval)
{
int size = Marshal.SizeOf(new uint());
var inOptionValues = new byte[size * 3];
BitConverter.GetBytes((uint)(on ? 1 : 0)).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)keepAliveTime).CopyTo(inOptionValues, size);
BitConverter.GetBytes((uint)keepAliveInterval).CopyTo(inOptionValues, size * 2);
socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
}
我还使用了异步读取:
socket.BeginReceive(packet.dataBuffer, 0, 128,
SocketFlags.None, new AsyncCallback(OnDataReceived), packet);
在回调中,这里是捕获的超时SocketException
,当socket在keep-alive数据包之后没有收到确认信号时引发。
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = socket.EndReceive(asyn);
}
catch (SocketException ex)
{
SocketExceptionCaught(ex);
}
}
这样,我就能够安全地检测到TCP客户端和服务器之间的连接断开。
发布于 2009-04-06 16:45:54
这根本是不可能的。您和服务器之间没有物理连接(除非在极少数情况下,您使用环回电缆在两台计算机之间连接)。
当连接正常关闭时,另一端会收到通知。但是如果连接是以其他方式断开的(比如用户连接断开),那么服务器直到超时才会知道(或者尝试写入连接,然后ack超时)。这就是TCP的工作方式,您必须接受它。
因此,“即时”是不现实的。您能做的最好的事情就是在超时时间内完成,这取决于运行代码的平台。
编辑:如果你只是在寻找优雅的连接,那么为什么不从你的客户端向服务器发送一个“断开”命令呢?
https://stackoverflow.com/questions/722240
复制相似问题