Socket 中级篇(一)Socket断开后要自动重连的常用几种方法:Connected、心跳包、recv()返回值==

发布时间:2024-12-09 15:47

地震后,避开断落的电线和煤气管道,尽快向开阔地移动,不要立即返回家中。 #生活常识# #应急生存技巧# #地震防护知识#

第一章、简介(抛出问题)

    参考:https://www.cnblogs.com/youxin/p/4056041.html

     功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一条socket连接。这就涉及到一个问题,如果socket连接断开(异常,正常)后,我如何才能感知到?server端这边是绝对被动的,sever端不能主动断开连接。也没有连接链路维持包之类的。client端发送数据的时间也是不定的。在socket连接断开后, server要能够感知到并释放资源。

1.1、服务器如何判断客户端与服务端是否断开?

       往往来说,服务器是不会断开,我们经常要考虑的是客户端的断开重连问题。

     方法1:发心跳包(超时未回复则断开,释放宽带等资源)

       客户端定时(比如30s发一次)地发心跳包给服务端,服务器给客户端发一个响应信号。如果服务器没有收到心跳包,那就是掉线了。这时候,我们就要释放该用户的资源。待客户端连接请求的时候,我们再建立一个Socket对象给该用户,即重新建立连接。

       参考:https://q.cnblogs.com/q/63760/

    方法2: Client.Receive()== 0(简单便捷、资源不缺情况下可用该方法)

       客户端连接状态有数据接收,Receive返回值 > 0。连接状态无数据接收,Receive会一直等待,不存在返回值的说明。断开状态下 Receive返回值 == 0。

      所以,我们可以用 Receive返回值 == 0判断是否断开。

    方法3:select()返回值==1,且recv()返回值为0 

     参考https://www.cnblogs.com/ranjiewen/p/5723936.html(这篇博客提供了5种方法)

         https://www.cnblogs.com/jacklikedogs/p/3976208.html

    方法四:socket.Poll()方法+Connected属性

参考:https://www.cnblogs.com/cuisir/p/8522680.html

https://blog.csdn.net/phker/article/details/71169887

if (list[i].Poll(1000, SelectMode.SelectRead))

{

list[i].Close();

list.RemoveAt(i);

continue;

}

  方法五:socket类Connected属性

在断开状态下,Connected = false

在连接状态下, Connected = true

1.2、我该用哪种方法来判断?

       不是所有的方法都适合自己的场景,带宽等资源足够、用户链接较少的情况下,建议采用第一章的方法2。否则,若是服务器级别,由于资源比较珍贵,用户比较多,建议采用方法1。

二、我的实现思路(Client.Receive()== 0 + Client.Connected ==false)

参考:

https://blog.csdn.net/lexjay/article/details/80535030

http://www.7kb.org/313.html重点

https://blog.csdn.net/u014722754/article/details/51318583(重点重点)

经过我的测试,采用(Client.Receive()== 0 + Client.Connected ==false)两者结合的方式,可以解决自动重连问题。

我们必须注意:

A、当正常连接状态,且服务器没有给客户端发数据时。  循环扫描一直停留在iRecBuffeActualByteCount = Client.Receive(btRecBuffer);这一步,知直到收到服务发过来的数据为止。(后面我们会附上全部代码)

B、一旦服务器断开,那么iRecBuffeActualByteCount就等于0,即iRecBuffeActualByteCount ==0。也就是说,我们可以通过判断iRecBuffeActualByteCount == 0 ,然后执行自动重连的方法。(后面我们会附上全部代码)

C、断开瞬间Client.Receive()== 0,但是 Client.Connected ==true。经过一会后, Client.Connected才等于false。

所以我们不能单单用 Client.Connected==false判断是否断开,这点是特别需要注意的。

2.1、步骤一

定义断开重连的方法,返回Socket。

private Socket ReConnet(Socket socketVar)

{

Socket Client = socketVar;

if (Client != null)

{

Client.Connect(serverIPEndPoint);

MessageBox.Show("连接不上,自动重连");

}

if (Client.Connected == false)

{

Client.Connect(serverIPEndPoint);

MessageBox.Show("连接不上,点击重连");

}

return Client;

}

在接收端,把这个方法用起来:

 但是该方法会报错,错误信息:

       断开套接字连接后,只能通过异步方式再次重新连接,而且只能连接到不同的 EndPoint。在操作完成前,在将不会退出的线程上必须调用 BeginConnect。

        因为套接字断开后,不能通过同步的方式,再次连接到同一个EndPoint。在该方法中,断开连接后,我们还是用了之前的Client对象。所以,该方法不可用。那么我们的解决方法是,在方法二里面,重新创建一个Client对象,并重新请求连接。

https://blog.csdn.net/baronyang/article/details/72779761

https://blog.csdn.net/phker/article/details/71169887

https://bbs.csdn.net/topics/370176926

方法二、重新创建一个Client对象,并重新请求连接

        网上,有很多人遇到同样的问题,不解释了,自己上代码。

https://blog.csdn.net/baronyang/article/details/72779761

https://www.cnblogs.com/friendan/archive/2012/06/03/2838167.html

网址:Socket 中级篇(一)Socket断开后要自动重连的常用几种方法:Connected、心跳包、recv()返回值== https://www.yuejiaxmz.com/news/view/425075

相关内容

Home按键然后锁屏,socket断开连接问题处理(error code=57)
Nico,从零开始干掉 Appium,移动端自动化测试框架实现(一) · 测试之家
基于python3的socket聊天编程
WAT网站压力测试工具
绿色数据中心助通信业节能降耗
物联网海量设备心跳注册,脱网清除——多线程高并发互斥锁落地
5个实用的自动化Python脚本
移动App的推送技术
压力测试工具下载 Socket Client Tester(压力测试软件) v1.0 免费绿色版 下载
压测工具如何选择? ab、locust、Jmeter、go压测工具【单台机器100w连接压测实战】

随便看看