TCP通讯客户端怎样判断与服务器端断开

longyuan_zw 2012-03-13 03:31:25
大虾们,神们,C# winform里面,采用多线程监听端口,接收方式为阻塞式,创建单一线程进行监听函数,这样阻塞时只阻塞单一线程,对主线程没有影响,并使用异步通信模式,来一个连接后回调函数进行解析入库。这是我的实现原理,目前有个问题,如何在客户端检测到与服务器断开,目前我只能做到写入TXT文档里面,看文档查看最后一次连接时间,如下:
------------------------告警信息2012-2-22 23:31:04--------------------------
共计接收300条数据,接收数据长度为:297字节,换算单位为0KB,解析与过滤后没有符合条件的数据入库!

如何在客户端检测到与服务器断开
...全文
4060 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
pengzhihui2012 2012-08-08
  • 打赏
  • 举报
回复
你好,这个问题我做了实验,当tcp服务器因为断电硬件故障异常断线的时候,客户端的系统会像你的tcp连接进程发一个SIGPIPE,系统默认的处理方式是终止进程。所以在你写的客户端里面你要用 signal()函数处理此信号,我利用信号的注册函数去重连(关闭以前的socket,重新建立socket),可以继续通信,后面我写个tcp服务器,用select监控客户端发来的数据,当客户端退出的时候,此时有3s左右的时间那个select一直可读,不知道为什么,求指教.........谢谢
longyuan_zw 2012-03-13
  • 打赏
  • 举报
回复
谢谢各位
白色的海 2012-03-13
  • 打赏
  • 举报
回复
完全同意楼上的。
一种就是用心跳包来维护连接,在发送心跳包异常时,可以认为对方短线,或者指定时间超时后,未收到对方的心跳响应,也认为是对方短线。
或者就是Send的时候会直接报异常,可以直接认为是掉线了。
MetalMax 2012-03-13
  • 打赏
  • 举报
回复
你可以用一个单独的线程来维护这个连接,具体的方法就是每个一个时间就向服务器/客户机 发送一段连接信息,
当接收方收到之后马上就回复发送方。
然后设置一个超时时间,过了时间就反复发几次。如果都没有收到回复。就可以判断连接断开了。这种方式就是上面几位说的“心跳包”
nonocast 2012-03-13
  • 打赏
  • 举报
回复
TCP设计就是无法获取实时连线状况,只有在Send时会主动产生Exception返回状态
你可以1分钟发送一次数据到服务端,这样client在Send时就知道和服务器是否断开,
那么在server用一个Dictionary记录最后心跳时间,超过3分钟认为client下线即可
gxingmin 2012-03-13
  • 打赏
  • 举报
回复
socket有Connected属性,可以判断这个属性是否是true,
true表示已连接,false表示未链接

在接收数据事件里可以通过try catch判断是否断开链接

private void OnRecievedData(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
int recvCount = sock.EndReceive(ar);

if (recvCount < 1)
{
//断开链接
return;
}
else
{
//正常链接,接收数据
}
AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
sock.BeginReceive( buff, 0, buff.Length, SocketFlags.None, recieveData, sock ); }
catch(...)
{
//断开了链接

}


}
nonocast 2012-03-13
  • 打赏
  • 举报
回复
用心跳包来检测短线情况
longyuan_zw 2012-03-13
  • 打赏
  • 举报
回复
不好意思,第一次发帖不知道还有结贴,这次第二次发帖一定结贴,请各位大侠们指教

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧