C# TcpClient 连接状态检测

wwwzhucom 2015-04-14 06:21:01
使用TcpClient和TcpListener编写了服务器端程序,并且使用的是异步处理;现有如下情景,请问怎么检测TcpClient的当前连接状态啊?客户端和服务器建立了连接,在服务器端的数组中保存了这个连接,然后客户端突然断开,当客户端再次重启后又和服务器建立了一个socket连接,服务器把第二个链接也保存到了数组,请问,如何检测第一个链接的当前连接状态?网上很多人使用了如下的方法,貌似这种方法并不能准确的判断当前的连接状态,请问有什么好的方法吗?
public static bool IsOnline(this TcpClient c)
{
return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected);
}
...全文
1799 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
SomethingJack 2015-10-12
  • 打赏
  • 举报
回复
楼主最后是怎么解决的??
changuncle 2015-08-16
  • 打赏
  • 举报
回复
看起来好高深的样子,感觉sp1234好懂啊好多帖子都能看到它的身影,谢谢各位了,又长见识了。
足球中国 2015-04-19
  • 打赏
  • 举报
回复
目前所有这方面程序通用的做法是用心跳包。 就是在客户端或服务器端在某个时间段,发送一个包,客户端或服务器端回复这个包。如果收到回复说明在线。否则就不在线了,就可以断掉当前连接。
江南小鱼 2015-04-18
  • 打赏
  • 举报
回复
引用 7 楼 wwwzhucom 的回复:
[quote=引用 6 楼 lovelj2012 的回复:] 心跳检测的时候,如果客户端没有影响,从数组中移除。
我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口[/quote] 客户端死掉,显然你这是同步。 另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。
wwwzhucom 2015-04-18
  • 打赏
  • 举报
回复
引用 6 楼 lovelj2012 的回复:
心跳检测的时候,如果客户端没有影响,从数组中移除。
我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口
江南小鱼 2015-04-18
  • 打赏
  • 举报
回复
心跳检测的时候,如果客户端没有影响,从数组中移除。
江南小鱼 2015-04-18
  • 打赏
  • 举报
回复
引用 3 楼 wwwzhucom 的回复:
[quote=引用 2 楼 sp1234 的回复:] 你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。
这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了[/quote] 心跳检测,就是每个一个时间间隔,发1个字节过去,有响应证明连接没断。
wwwzhucom 2015-04-18
  • 打赏
  • 举报
回复
引用 1 楼 liucatch 的回复:
1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接; 2.增加心跳,根据心跳超时来判断;
如果使用了第一个连接(发送数据),也就是说使用了那个所谓断开的连接,然后我的服务就死掉了
wwwzhucom 2015-04-18
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。
这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了
  • 打赏
  • 举报
回复
可能你总是努力“理解”别人说的话,要求别人“详细点”。 但是实际上,对于程序设计人员来说,至少有一半技术是因为“不纠结于是非”而才能够真正集中精力去了解的,是通过掌握调试方法来获得的。如果你反反复复地拿出多条代码问别人“这样写是对的么?”,貌似挺好学而实际上总是转移焦点,别人估计以后就跳过你的问题你了。你要把问题调试到具体代码、具体变量上,这样才有意义。
  • 打赏
  • 举报
回复
引用 11 楼 wwwzhucom 的回复:
[quote=引用 10 楼 sp1234 的回复:] “死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。
我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?[/quote] 唉,你写了什么语句不重要,重要地是你说的“服务器就死掉了”是这一条语句上一直在等待吗? 贴出你的调试画面来。你都懒得去“自己找到”哪一条语句上造成了“死掉”的问题,别人说什么对于你这个接受方式都是多余的啊。
江南小鱼 2015-04-18
  • 打赏
  • 举报
回复
引用 9 楼 wwwzhucom 的回复:
[quote=引用 8 楼 lovelj2012 的回复:] [quote=引用 7 楼 wwwzhucom 的回复:] [quote=引用 6 楼 lovelj2012 的回复:] 心跳检测的时候,如果客户端没有影响,从数组中移除。
我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口[/quote] 客户端死掉,显然你这是同步。 另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。[/quote] 首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?[/quote] 一个客户端断开,整个服务端死掉,腾讯如果象你怎么玩,早倒闭了 你的虽然是BeginWrite,异步发送,但是服务端只有一个实例监听、发送以及应答,不死才怪呢。 仔细阅读这篇博文,可能对你的代码重构有帮助。 http://www.cnblogs.com/JimmyZhang/archive/2008/09/07/1286299.html
wwwzhucom 2015-04-18
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。
我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?
  • 打赏
  • 举报
回复
“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。
wwwzhucom 2015-04-18
  • 打赏
  • 举报
回复
引用 8 楼 lovelj2012 的回复:
[quote=引用 7 楼 wwwzhucom 的回复:] [quote=引用 6 楼 lovelj2012 的回复:] 心跳检测的时候,如果客户端没有影响,从数组中移除。
我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口[/quote] 客户端死掉,显然你这是同步。 另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。[/quote] 首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?
  • 打赏
  • 举报
回复
你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。
liucatch 2015-04-14
  • 打赏
  • 举报
回复
1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接; 2.增加心跳,根据心跳超时来判断;

110,533

社区成员

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

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

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