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

2023-10-29

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

    参考: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)) 
//SelectMode.SelectRead表示,如果已调用 并且有挂起的连接,true。
//- 或 - 如果有数据可供读取,则为 true。- 或 - 如果连接已关闭、重置或终止,则返回 true(此种情况就表示若客户端断开连接了,则此方法就返回true); 否则,返回 false。
{
     list[i].Close();//关闭socket
     list.RemoveAt(i);//从列表中删除断开的socke
     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。

        /// <summary>
        /// 断开重连
        /// </summary>
        /// <param name="socketVar"></param>
        /// <returns></returns>
        private Socket ReConnet(Socket socketVar)
        {
            Socket Client = socketVar;
            //bool blIsConneted = false;
            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

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • socket、tcp、udp、http 的认识及区别

    网络由下往上分为物理层 数据链路层 网络层 传输层 会话层 表示层和应用层 IP 协议对应于网络层 TCP协议对应于传输层 HTTP协议对应于应用层 三者从本质上来说没有可比性 socket则是对TCP IP协议的封装和应用 可以说 TPC
  • linux内核中socket读取和接收的缓冲区大小

    linux内核中socket读取和接收的缓冲区大小 1 socket内核缓冲区大小可用getsockopt获取 2 socket内核缓冲区大小可用setsockopt设置 缓冲区的大小为设置的值的2倍 具体设置代码入下 3 socket缓冲
  • QT中UDPSocket丢包问题

    1 配置和编程 下位机向上位机发送UDP数据包 由于UDP小包不能写太大 每个小包也就1kB左右 下位机周期性地发送数据 每个周期发送数百个udp包 并且是使用while死循环来发送的 上位机使用QUdpSocket类接收UDP数据 采用信
  • MFC实现socket网络通信--主机与服务器之间传送数据

    MFC实现socket网络通信 模拟主机与服务器之间传送数据 MFC实现socket网络通信 1 新建MFC应用程序 2 创建服务端窗口界面 3 写服务器代码 4 创建客户端窗口界面 5 客户端代码部分 6 开始调试 7 小结 MFC实现s
  • ‘windows socket error:由于目标机器积极拒绝,无法连接。(10061),on API 'connect'的错误?

    1 gt 连接时出现 windows socket error 10061 on API connect 是SOCKET没有启动 SCKTSRVR EXE 或者无法连接到服务器 端口等 使用socketconnect很简单 只要在应用服务器
  • 关于非同一局域网下两台设备之间的网络通信(服务器的作用)

    看过很多关于局域网下的两台设备之间的通信方式 最多的就是通过socket进行tcp ip通信 建立一个服务端 再建立一个客户端 客户端向服务端发起请求连接 然后再进行两端的通信 但发现其实这却存在着很多的问题与不足 如果是不在同一局域网下的
  • JDK8 网络Net包研究(一)

    网络基础 1 国际标准化组织的OSI 开放式系统互联模型 七层模型 2 TCP IP协议 组 四层模型 3 TCP IP协议组 一组包括TCP协议和IP协议 UDP协议 ICMP协议和其他一些协议的协议组 网络层 IP协议 gt 网络互连协
  • Socket -- udp

    接收者 完成System out println UDPProvider Started 作为接收者 指定一个端口用于数据接收 DatagramSocket ds new DatagramSocket 20000 构建接收实体 final
  • 网络编程——epoll

    参考 TCP IP网络编程 尹圣雨 epoll epoll也是Linux下实现I O复用的一种方法 其性能优于select 基于select的I O复用服务器的设计缺陷 调用select函数后 针对所有文件描述符的循环语句 调用select
  • Java swing + socket 写的一个五子棋网络对战游戏

    自从开始接触Swing以来 就喜欢写写各种管理系统 写多了就萌生了一种类似于实时在线对战的游戏 经过一番构思后就开始着手设计这个网络对战版本的五子棋了 游戏代码包含两部分 常规的C S模式 C代表客户端 S代表服务端 下载代码后先启动服务器
  • Java Socket聊天室

    Socket聊天室 1 创建登录判断类UserLogin 2 创建登录服务器LoginServer 3 创建聊天服务器ChatServer 4 创建客户端Client 5 创建服务器用于处理聊天的线程类ChatThread 6 创建客户端C
  • 基于TCP的socket通信

    本文转载自http blog csdn net chocolate001 article details 6612201 基于TCP 面向连接 的socket编程 分为客户端和服务器端 客户端的流程如下 1 创建套接字 socket 2 向
  • Socket_Tcp加密文件传输系统

    代码下载链接 Socket Tcp 原文链接 https blog csdn net weixin 45746588 article details 107683901 这是一个课程的作业 我是初学者 所以写完这个代码还是花了我好几周的时间
  • 【小练习】windows与linux进行socket文件传输

    在Windows与Linux使用socket通信基础上 添加文件传输功能 需要进行简单的交互 目录 程序效果 实现流程 样例代码 测试用例 参考资料 程序效果 Windows客户端可以从Linux服务器端索要文件 也可以发送文件至Linux
  • Go_一文入门网络编程:常见协议、通信过程、Socket、CS/BS、TCP/UDP

    网络编程三要素 ip地址 端口 协议 在网络通信协议下 不同计算机上运行的程序 可以进行数据传输 IP地址 IP地址是一种在互联网协议中用于识别和定位设备的32位或128位数字地址 它是一个设备在网络上的唯一标识符 用于在互联网上定位和识别
  • Windows平台下MingGW的网络socket编程模型

    Windows平台下MingGW的网络socket编程模型 1 TCP服务器 include
  • socket,socket.io,mongodb

    Socket 网络上的程序实现双向的数据链接 这个链接的一端成为socket 1 Socket是一个持久链接 2 Socket是双向通信的 Socket VS ajax轮询 ajax轮询 是利用客户端来发送请求 每隔几秒发送一个http请求
  • SocketOutputStream和SocketChannel write方法的区别和底层实现

    Java直接内存原理提到了SocketChannel write的实现原理 通过IOUtil write将java堆内存拷贝到了直接内存 然后再把地址传给了I O函数 那么 BIO 是怎么实现往socket里面写数据的呢 BIO Socke
  • socket连接超时问题

    一部分 把CSDN与中文yahoo翻了底朝天 也没找到如何设置socket的连接超时的满意方法 问此问题的兄弟已有一大堆 这里偶就讲一下win下如何设置socket的connect超时 设置connect的超时很简单 CSDN上也有人提到过
  • linux send recv函数详解

    2009 05 10 21 55 int send SOCKET s const char FAR buf int len int flags 不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据 客户程序一般用sen

随机推荐