怎样得知TCP客户端的socket的连接是否被断开?

245 views
Skip to first unread message

光与影

unread,
Dec 27, 2006, 8:05:58 PM12/27/06
to 高性能网络编程邮件列表
通过TCP协议连接的客户端socket和服务端socket,断开连接有两种情况:
1、如果客户端主动断开连接,服务端会触发异常或跳出阻塞状态(服务端socket平时处于receive状态),服务端socket可以由此获知连接被断开了。
2、如果是服务端主动断开连接,例如服务端觉得连接了很长时间都处于空闲状态,要主动断开跟客户端的连接,这时客户端如果不是正在发送或接收数据的话(即处于空闲状态下)是完全不知情的。直到想发送数据到服务端时才发现连接已经断开了。

现在的问题是:对于第二种情况,如果客户端想在发送数据给服务端之前就判断一下连接是否被断开,有什么解决的方法呢?

ps:我的程序是用C#实现的,.Net的socket实现的是Berkeley
Socket。

zhu weijie

unread,
Dec 27, 2006, 11:58:38 PM12/27/06
to dev4s...@googlegroups.com
如果正常情况如果连接已经断开,客户端的发送马上就会出错并返回,如果服务端不是主动断开,而是出现异常或者当机这时候客户端会不知道连接已经不存在,需要利用保活或者是超时机制。

秦一

unread,
Dec 28, 2006, 7:32:52 PM12/28/06
to dev4s...@googlegroups.com
可以设置一个定时器,用于检测连线状态。

在06-12-28,zhu weijie <zhuwei...@gmail.com> 写道:

光与影

unread,
Dec 28, 2006, 11:36:43 PM12/28/06
to 高性能网络编程邮件列表
我是想在客户端每次发送数据之前获取连接是否仍通,如果确定了仍然连通的话再发送数据出去。

sunway

unread,
Dec 29, 2006, 12:22:52 AM12/29/06
to 高性能网络编程邮件列表
这类基础问题到CSDN里找找老帖子看看把

光与影

unread,
Jan 1, 2007, 3:50:23 AM1/1/07
to 高性能网络编程邮件列表
拜托你看清题目再说好不好。不要说csdn,就用英文搜索都是到目前为止都还没有人有直接的解决方法,客户端只能先在发送之后看看是否有异常才能知道自己是否已经连通的。
我现在基本上可以确定应该是没有直接的方法,在MSDN论坛里面有人建议发送0字节以试探是否连通,在C#里面这个方法是不行的。附代码:

// .Connect throws an exception if unsuccessful
client.Connect(anEndPoint);

// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
byte [] tmp = new byte[1];

client.Blocking = false;
client.Send(tmp, 0, 0);
Console.WriteLine("Connected!");
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
Console.WriteLine("Still Connected, but the Send would block");
else
{
Console.WriteLine("Disconnected: error code {0}!",
e.NativeErrorCode);
}
}
finally
{
client.Blocking = blockingState;
}

Console.WriteLine("Connected: {0}", client.Connected);

"sunway 写道:
"
> 这类基础问题到CSDN里找找老帖子看看把

chuanwen chen

unread,
Jan 1, 2007, 6:32:03 AM1/1/07
to dev4s...@googlegroups.com
客户端:发送数据包可以从协议栈API函数返回值知道
服务器,采用heatbeat

iceboundrock

unread,
Jan 1, 2007, 8:50:44 AM1/1/07
to 高性能网络编程邮件列表
客户端-服务器需要保持长连接的程序,目前普遍都是通过客户端定时向服务器发送心跳数据包来证明连接状态的。
我最近写了一篇blog,讲述如何使用双向链表和Hashtable来加速处理"心跳"超时检测的,欢迎大家指导
http://www.cnblogs.com/ncindy/archive/2006/12/30/607608.html

sunway

unread,
Jan 1, 2007, 9:47:16 AM1/1/07
to 高性能网络编程邮件列表
这个问题的解决办法通常就是用心跳包来解决。其他办法也就是开KEEPLIVE,应该是个很基础的问题。

yaoa...@eyou.com

unread,
Jan 5, 2007, 3:51:16 AM1/5/07
to 高性能网络编程邮件列表
C#我不懂,我想了解一下,如果是socket
API,用select行不行啊?就是说套接字发生任何变化,select是不是都会有反映?

iceboundrock

unread,
Jan 5, 2007, 9:23:25 PM1/5/07
to 高性能网络编程邮件列表
按照我的理解,其实select检测的是本机网络接口(比如网卡)驱动这一层的buffer状况。所以select不会反馈一个连接意外被破坏的情况。

sunway

unread,
Jan 5, 2007, 9:40:14 PM1/5/07
to 高性能网络编程邮件列表
摁,要想检测断开,必须发送保持连接包或者打开keep
alive,
Reply all
Reply to author
Forward
0 new messages