Socket 中级篇(一)Socket断开后要自动重连的常用几种方法:Connected、心跳包、recv()返回值== |
您所在的位置:网站首页 › winsock编程vb › Socket 中级篇(一)Socket断开后要自动重连的常用几种方法:Connected、心跳包、recv()返回值== |
第一章、简介(抛出问题)
参考: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。 /// /// 断开重连 /// /// /// 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
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |