C# TcpClient 连接状态检测

时间:2022-11-10 15:20:18
使用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);
}

17 个解决方案

#1


1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接;
2.增加心跳,根据心跳超时来判断;

#2


你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。

#3


引用 2 楼 sp1234 的回复:
你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。


这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了

#4


引用 1 楼 liucatch 的回复:
1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接;
2.增加心跳,根据心跳超时来判断;


如果使用了第一个连接(发送数据),也就是说使用了那个所谓断开的连接,然后我的服务就死掉了

#5


引用 3 楼 wwwzhucom 的回复:
Quote: 引用 2 楼 sp1234 的回复:

你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。


这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了

心跳检测,就是每个一个时间间隔,发1个字节过去,有响应证明连接没断。

#6


心跳检测的时候,如果客户端没有影响,从数组中移除。

#7


引用 6 楼 lovelj2012 的回复:
心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

#8


引用 7 楼 wwwzhucom 的回复:
Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。

#9


引用 8 楼 lovelj2012 的回复:
Quote: 引用 7 楼 wwwzhucom 的回复:

Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。


首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?

#10


“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。

#11


引用 10 楼 sp1234 的回复:
“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。


我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?

#12


引用 9 楼 wwwzhucom 的回复:
Quote: 引用 8 楼 lovelj2012 的回复:

Quote: 引用 7 楼 wwwzhucom 的回复:

Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。


首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?

一个客户端断开,整个服务端死掉,腾讯如果象你怎么玩,早倒闭了 C# TcpClient 连接状态检测

你的虽然是BeginWrite,异步发送,但是服务端只有一个实例监听、发送以及应答,不死才怪呢。
仔细阅读这篇博文,可能对你的代码重构有帮助。
http://www.cnblogs.com/JimmyZhang/archive/2008/09/07/1286299.html

#13


引用 11 楼 wwwzhucom 的回复:
Quote: 引用 10 楼 sp1234 的回复:

“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。


我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?


唉,你写了什么语句不重要,重要地是你说的“服务器就死掉了”是这一条语句上一直在等待吗?

贴出你的调试画面来。你都懒得去“自己找到”哪一条语句上造成了“死掉”的问题,别人说什么对于你这个接受方式都是多余的啊。

#14


可能你总是努力“理解”别人说的话,要求别人“详细点”。

但是实际上,对于程序设计人员来说,至少有一半技术是因为“不纠结于是非”而才能够真正集中精力去了解的,是通过掌握调试方法来获得的。如果你反反复复地拿出多条代码问别人“这样写是对的么?”,貌似挺好学而实际上总是转移焦点,别人估计以后就跳过你的问题你了。你要把问题调试到具体代码、具体变量上,这样才有意义。

#15


目前所有这方面程序通用的做法是用心跳包。
就是在客户端或服务器端在某个时间段,发送一个包,客户端或服务器端回复这个包。如果收到回复说明在线。否则就不在线了,就可以断掉当前连接。

#16


看起来好高深的样子,感觉sp1234好懂啊好多帖子都能看到它的身影,谢谢各位了,又长见识了。

#17


楼主最后是怎么解决的??

#1


1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接;
2.增加心跳,根据心跳超时来判断;

#2


你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。

#3


引用 2 楼 sp1234 的回复:
你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。


这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了

#4


引用 1 楼 liucatch 的回复:
1.可以统计发送和接收的总字节数,单开一个线程遍历存放的链接,如果指定时间内发送和接收字节数没有变化,可以认为当前的连接已经断开,移除这个连接;
2.增加心跳,根据心跳超时来判断;


如果使用了第一个连接(发送数据),也就是说使用了那个所谓断开的连接,然后我的服务就死掉了

#5


引用 3 楼 wwwzhucom 的回复:
Quote: 引用 2 楼 sp1234 的回复:

你检测的那些,都是“上一次通讯的结果”,跟当前状态无关。要知道当前状态,你就要实际去发送信息(1个或者0个字节)。


这种方法我也试过,好像不行,你能写一个检测TcpClient当前连接的方法吗,谢谢了

心跳检测,就是每个一个时间间隔,发1个字节过去,有响应证明连接没断。

#6


心跳检测的时候,如果客户端没有影响,从数组中移除。

#7


引用 6 楼 lovelj2012 的回复:
心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

#8


引用 7 楼 wwwzhucom 的回复:
Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。

#9


引用 8 楼 lovelj2012 的回复:
Quote: 引用 7 楼 wwwzhucom 的回复:

Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。


首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?

#10


“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。

#11


引用 10 楼 sp1234 的回复:
“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。


我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?

#12


引用 9 楼 wwwzhucom 的回复:
Quote: 引用 8 楼 lovelj2012 的回复:

Quote: 引用 7 楼 wwwzhucom 的回复:

Quote: 引用 6 楼 lovelj2012 的回复:

心跳检测的时候,如果客户端没有影响,从数组中移除。


我知道,关键是把发送代码一执行完,我的服务器就死掉了,客户端是手机端和设备端,它们的IP和端口是随时分配的,我推送消息时是从数组中找到这个连接然后发送出去的,所以会死掉,客户端不是固定的IP和端口

客户端死掉,显然你这是同步。
另外,检测的时候设置超时时间,超时连接不上,视为连接已断开。


首先是设备端或手机客户端断开,然后再使用断开的连接发送数据,我这边就死掉了,有什么方法可以使我这边的连接不断开?

一个客户端断开,整个服务端死掉,腾讯如果象你怎么玩,早倒闭了 C# TcpClient 连接状态检测

你的虽然是BeginWrite,异步发送,但是服务端只有一个实例监听、发送以及应答,不死才怪呢。
仔细阅读这篇博文,可能对你的代码重构有帮助。
http://www.cnblogs.com/JimmyZhang/archive/2008/09/07/1286299.html

#13


引用 11 楼 wwwzhucom 的回复:
Quote: 引用 10 楼 sp1234 的回复:

“死掉”是你的程序的用户体验差,跟技术本身没有关系。假设一个QQ它连不上网了就立刻让界面“死”了30秒,那显然是“同步、异步”程序设计问题。发送数据是应该在“后台异步”去做的事情,而你把它弄到“前台”来做了。


我使用的是NetworkStream.BeginWrite 方法向流中异步写入数据.我对“后台异步”和“前台”不是很理解,能详细点吗?还有,如果手机端或设备端使用同步对我这边有影响吗?


唉,你写了什么语句不重要,重要地是你说的“服务器就死掉了”是这一条语句上一直在等待吗?

贴出你的调试画面来。你都懒得去“自己找到”哪一条语句上造成了“死掉”的问题,别人说什么对于你这个接受方式都是多余的啊。

#14


可能你总是努力“理解”别人说的话,要求别人“详细点”。

但是实际上,对于程序设计人员来说,至少有一半技术是因为“不纠结于是非”而才能够真正集中精力去了解的,是通过掌握调试方法来获得的。如果你反反复复地拿出多条代码问别人“这样写是对的么?”,貌似挺好学而实际上总是转移焦点,别人估计以后就跳过你的问题你了。你要把问题调试到具体代码、具体变量上,这样才有意义。

#15


目前所有这方面程序通用的做法是用心跳包。
就是在客户端或服务器端在某个时间段,发送一个包,客户端或服务器端回复这个包。如果收到回复说明在线。否则就不在线了,就可以断掉当前连接。

#16


看起来好高深的样子,感觉sp1234好懂啊好多帖子都能看到它的身影,谢谢各位了,又长见识了。

#17


楼主最后是怎么解决的??