判断socket是否断开 用disconnect 断开,再重新连接怎么搞

博客访问: 182218
博文数量: 54
博客积分: 0
博客等级: 民兵
技术积分: 575
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C#/.net
一、网上常用方法
1、当Socket.Conneted == false时,调用如下函数进行判断
点击(此处)折叠或打开
/// 当socket.connected为false时,进一步确定下当前连接状态
private bool IsSocketConnected()
&&&&#region remarks
&&&&/********************************************************************************************
&&&&&* 当Socket.Conneted为false时, 如果您需要确定连接的当前状态,请进行非阻塞、零字节的 Send 调用。
&&&&&* 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;
&&&&&* 否则,该套接字不再处于连接状态。
&&&&&* Depending on /zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
&&&&********************************************************************************************/
&&&&#endregion
&&&&#region 过程
&&&&&&&&&&&&// This is how you can determine whether a socket is still connected.
&&&&&&&&&&&&bool connectState = true;
&&&&&&&&&&&&bool blockingState = socket.Blocking;
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&byte[] tmp = new byte[1];
&&&&&&&&&&&&&&&&socket.Blocking = false;
&&&&&&&&&&&&&&&&socket.Send(tmp, 0, 0);
&&&&&&&&&&&&&&&&//Console.WriteLine("Connected!");
&&&&&&&&&&&&&&&&connectState = true; //若Send错误会跳去执行catch体,而不会执行其try体里其之后的代码
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (SocketException e)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&// 10035 == WSAEWOULDBLOCK
&&&&&&&&&&&&&&&&if (e.NativeErrorCode.Equals(10035))
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//Console.WriteLine("Still Connected, but the Send would block");
&&&&&&&&&&&&&&&&&&&&connectState = true;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
&&&&&&&&&&&&&&&&&&&&connectState = false;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&finally
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&socket.Blocking = blockingState;
&&&&&&&&&&&&}
&&&&&&&&&&&&//Console.WriteLine("Connected: {0}", client.Connected);
&&&&&&&&&&&&return connectState;
&&&&&&&&&&&&#endregion
2、根据socket.poll判断
点击(此处)折叠或打开
/// 另一种判断connected的方法,但未检测对端网线断开或ungraceful的情况
static bool IsSocketConnected(Socket s)
&&&&#region remarks
&&&&&&&&&&&&/* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into conside&&&&&&&&&&&&&&&&ration
&&&&&&&&&&&&&* that the socket might not have been initialized in the first place.
&&&&&&&&&&&&&* This is the last (I believe) piece of information and it is supplied by the Socket.Connected property.
&&&&&&&&&&&&&* The revised version of the method would looks something like this:
&&&&&&&&&&&&&* from:/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c
&&&&&&&&&&&&#endregion
&&&&#region 过程
&&&&&&&&&&&&return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
&&&&&&&&&&&&/* The long, but simpler-to-understand version:
&&&&&&&&&&&&&&&&&&&&bool part1 = s.Poll(1000, SelectMode.SelectRead);
&&&&&&&&&&&&&&&&&&&&bool part2 = (s.Available == 0);
&&&&&&&&&&&&&&&&&&&&if ((part1 && part2 ) || !s.Connected)
&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&*/
&&&&&&&&&&&&#endregion
总结:--1--此两种方法出处可在函数体中的remark中找到链接
&&&&&&&& --2--此两种方法适用于对端正常关闭socket下的本地socket状态检测,在非正常关闭如断电、拔网线的情况下不起作用
&&&&&&&&&&&&&& 因为Socket.Conneted存在bug,详见
二、支持物理断线重连功能的类
&&&&&&& 利用BeginReceive + KeepAlive实现物理断线重连,初步测验了一下,正常。(部分代码参考及)
&&&&&&& Keep-Alive机制的介绍请看
&&&&&&& 以此备忘,同时希望能帮助到有需要的同学。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace MySocket
&&&&public class Socket_wrapper
&&&&&&&&//委托
&&&&&&&&private delegate void delSocketDataArrival(byte[] data);
&&&&&&&&static delSocketDataArrival socketDataArrival = socketDataArrivalHandler;
&&&&&&&&private delegate void delSocketDisconnected();
&&&&&&&&static delSocketDisconnected socketDisconnected = socketDisconnectedHandler;
&&&&&&&&public static Socket theSocket = null;
&&&&&&&&private static string remoteHost = "192.168.1.71";
&&&&&&&&private static int remotePort = 6666;
&&&&&&&&private static String SockErrorStr = null;
&&&&&&&&private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
&&&&&&&&private static Boolean IsconnectSuccess = false; //异步连接情况,由异步连接回调函数置位
&&&&&&&&private static object lockObj_IsConnectSuccess = new object();
&&&&&&&&///
&&&&&&&&/// 构造函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public Socket_wrapper(string strIp, int iPort)
&&&&&&&&&&&&remoteHost = strIp;
&&&&&&&&&&&&remotePort = iPort;
&&&&&&&&///
&&&&&&&&/// 设置心跳
&&&&&&&&///
&&&&&&&&private static void SetXinTiao()
&&&&&&&&&&&&//byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间20 秒, 间隔侦测时间2 秒
&&&&&&&&&&&&byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间5 秒, 间隔侦测时间2 秒
&&&&&&&&&&&&theSocket.IOControl(IOControlCode.KeepAliveValues, inValue, null);
&&&&&&&&///
&&&&&&&&/// 创建套接字+异步连接函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&private static bool socket_create_connect()
&&&&&&&&&&&&IPAddress ipAddress = IPAddress.Parse(remoteHost);
&&&&&&&&&&&&IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort);
&&&&&&&&&&&&theSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
&&&&&&&&&&&&theSocket.SendTimeout = 1000;
&&&&&&&&&&&&SetXinTiao();//设置心跳参数
&&&&&&&&&&&&#region 异步连接代码
&&&&&&&&&&&&TimeoutObject.Reset(); //复位timeout事件
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&theSocket.BeginConnect(remoteEP, connectedCallback, theSocket);
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (Exception err)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&SockErrorStr = err.ToString();
&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&}
&&&&&&&&&&&&if (TimeoutObject.WaitOne(10000, false))//直到timeout,或者TimeoutObject.set()
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if (IsconnectSuccess)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&return true;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&SockErrorStr = "Time Out";
&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&}
&&&&&&&&&&&&#endregion
&&&&&&&&///
&&&&&&&&/// 同步receive函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public string socket_receive(byte[] readBuffer)
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if (theSocket == null)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&socket_create_connect();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else if (!theSocket.Connected)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&if (!IsSocketConnected())
&&&&&&&&&&&&&&&&&&&&&&&&Reconnect();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&int bytesRec = theSocket.Receive(readBuffer);
&&&&&&&&&&&&&&&&if (bytesRec == 0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//warning 0 bytes received
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&return Encoding.ASCII.GetString(readBuffer, 0, bytesRec);
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (SocketException se)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//print se.ErrorCode
&&&&&&&&&&&&&&&&throw;
&&&&&&&&&&&&}
&&&&&&&&///
&&&&&&&&/// 同步send函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public bool socket_send(string sendMessage)
&&&&&&&&&&&&if (checkSocketState())
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&return SendData(sendMessage);
&&&&&&&&&&&&}
&&&&&&&&&&&&return false;
&&&&&&&&///
&&&&&&&&/// 断线重连函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&private static bool Reconnect()
&&&&&&&&&&&&//关闭socket
&&&&&&&&&&&&theSocket.Shutdown(SocketShutdown.Both);
&&&&&&&&&&&&theSocket.Disconnect(true);
&&&&&&&&&&&&IsconnectSuccess = false;
&&&&&&&&&&&&theSocket.Close();
&&&&&&&&&&&&//创建socket
&&&&&&&&&&&&return socket_create_connect();
&&&&&&&&///
&&&&&&&&/// 当socket.connected为false时,进一步确定下当前连接状态
&&&&&&&&///
&&&&&&&&///
&&&&&&&&private bool IsSocketConnected()
&&&&&&&&&&&&#region remarks
&&&&&&&&&&&&/********************************************************************************************
&&&&&&&&&&&&&* 当Socket.Conneted为false时, 如果您需要确定连接的当前状态,请进行非阻塞、零字节的 Send 调用。
&&&&&&&&&&&&&* 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;
&&&&&&&&&&&&&* 否则,该套接字不再处于连接状态。
&&&&&&&&&&&&&* Depending on /zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
&&&&&&&&&&&&********************************************************************************************/
&&&&&&&&&&&&#endregion
&&&&&&&&&&&&#region 过程
&&&&&&&&&&&&// This is how you can determine whether a socket is still connected.
&&&&&&&&&&&&bool connectState = true;
&&&&&&&&&&&&bool blockingState = theSocket.Blocking;
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&byte[] tmp = new byte[1];
&&&&&&&&&&&&&&&&theSocket.Blocking = false;
&&&&&&&&&&&&&&&&theSocket.Send(tmp, 0, 0);
&&&&&&&&&&&&&&&&//Console.WriteLine("Connected!");
&&&&&&&&&&&&&&&&connectState = true; //若Send错误会跳去执行catch体,而不会执行其try体里其之后的代码
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (SocketException e)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&// 10035 == WSAEWOULDBLOCK
&&&&&&&&&&&&&&&&if (e.NativeErrorCode.Equals(10035))
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//Console.WriteLine("Still Connected, but the Send would block");
&&&&&&&&&&&&&&&&&&&&connectState = true;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
&&&&&&&&&&&&&&&&&&&&connectState = false;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&finally
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&theSocket.Blocking = blockingState;
&&&&&&&&&&&&}
&&&&&&&&&&&&//Console.WriteLine("Connected: {0}", client.Connected);
&&&&&&&&&&&&return connectState;
&&&&&&&&&&&&#endregion
&&&&&&&&///
&&&&&&&&/// 另一种判断connected的方法,但未检测对端网线断开或ungraceful的情况
&&&&&&&&///
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public static bool IsSocketConnected(Socket s)
&&&&&&&&&&&&#region remarks
&&&&&&&&&&&&/* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into consideration
&&&&&&&&&&&&&* that the socket might not have been initialized in the first place.
&&&&&&&&&&&&&* This is the last (I believe) piece of information and it is supplied by the Socket.Connected property.
&&&&&&&&&&&&&* The revised version of the method would looks something like this:
&&&&&&&&&&&&&* from:/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c
&&&&&&&&&&&&#endregion
&&&&&&&&&&&&#region 过程
&&&&&&&&&&&&if (s == null)
&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
&&&&&&&&&&&&/* The long, but simpler-to-understand version:
&&&&&&&&&&&&&&&&&&&&bool part1 = s.Poll(1000, SelectMode.SelectRead);
&&&&&&&&&&&&&&&&&&&&bool part2 = (s.Available == 0);
&&&&&&&&&&&&&&&&&&&&if ((part1 && part2 ) || !s.Connected)
&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&*/
&&&&&&&&&&&&#endregion
&&&&&&&&///
&&&&&&&&/// 异步连接回调函数
&&&&&&&&///
&&&&&&&&///
&&&&&&&&static void connectedCallback(IAsyncResult iar)
&&&&&&&&&&&&#region <remarks>
&&&&&&&&&&&&/// 1、置位IsconnectSuccess
&&&&&&&&&&&&#endregion </remarks>
&&&&&&&&&&&&lock (lockObj_IsConnectSuccess)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Socket client = (Socket)iar.AsyncState;
&&&&&&&&&&&&&&&&try
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&client.EndConnect(iar);
&&&&&&&&&&&&&&&&&&&&IsconnectSuccess = true;
&&&&&&&&&&&&&&&&&&&&StartKeepAlive(); //开始KeppAlive检测
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&catch (Exception e)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//Console.WriteLine(e.ToString());
&&&&&&&&&&&&&&&&&&&&SockErrorStr = e.ToString();
&&&&&&&&&&&&&&&&&&&&IsconnectSuccess = false;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&finally
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&TimeoutObject.Set();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&///
&&&&&&&&/// 开始KeepAlive检测函数
&&&&&&&&///
&&&&&&&&private static void StartKeepAlive()
&&&&&&&&&&&&theSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket);
&&&&&&&&///
&&&&&&&&/// BeginReceive回调函数
&&&&&&&&///
&&&&&&&&static byte[] buffer = new byte[1024];
&&&&&&&&private static void OnReceiveCallback(IAsyncResult ar)
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Socket peerSock = (Socket)ar.AsyncState;
&&&&&&&&&&&&&&&&int BytesRead = peerSock.EndReceive(ar);
&&&&&&&&&&&&&&&&if (BytesRead > 0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&byte[] tmp = new byte[BytesRead];
&&&&&&&&&&&&&&&&&&&&Array.ConstrainedCopy(buffer, 0, tmp, 0, BytesRead);
&&&&&&&&&&&&&&&&&&&&if (socketDataArrival != null)
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&socketDataArrival(tmp);
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else//对端gracefully关闭一个连接
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&if (theSocket.Connected)//上次socket的状态
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&if (socketDisconnected != null)
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&//1-重连
&&&&&&&&&&&&&&&&&&&&&&&&&&&&socketDisconnected();
&&&&&&&&&&&&&&&&&&&&&&&&&&&&//2-退出,不再执行BeginReceive
&&&&&&&&&&&&&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&//此处buffer似乎要清空--待实现 zq
&&&&&&&&&&&&&&&&theSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket);
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (Exception ex)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if (socketDisconnected != null)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&socketDisconnected(); //Keepalive检测网线断开引发的异常在这里捕获
&&&&&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&///
&&&&&&&&/// 异步收到消息处理器
&&&&&&&&///
&&&&&&&&///
&&&&&&&&private static void socketDataArrivalHandler(byte[] data)
&&&&&&&&///
&&&&&&&&/// socket由于连接中断(软/硬中断)的后续工作处理器
&&&&&&&&///
&&&&&&&&private static void socketDisconnectedHandler()
&&&&&&&&&&&&Reconnect();
&&&&&&&&///
&&&&&&&&/// 检测socket的状态
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public static bool checkSocketState()
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if (theSocket == null)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&return socket_create_connect();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else if (IsconnectSuccess)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&return true;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else//已创建套接字,但未connected
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&#region 异步连接代码
&&&&&&&&&&&&&&&&&&&&TimeoutObject.Reset(); //复位timeout事件
&&&&&&&&&&&&&&&&&&&&try
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&IPAddress ipAddress = IPAddress.Parse(remoteHost);
&&&&&&&&&&&&&&&&&&&&&&&&IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort);
&&&&&&&&&&&&&&&&&&&&&&&&theSocket.BeginConnect(remoteEP, connectedCallback, theSocket);
&&&&&&&&&&&&&&&&&&&&&&&&SetXinTiao();//设置心跳参数
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&catch (Exception err)
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&SockErrorStr = err.ToString();
&&&&&&&&&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&if (TimeoutObject.WaitOne(2000, false))//直到timeout,或者TimeoutObject.set()
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&if (IsconnectSuccess)
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&return true;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&SockErrorStr = "Time Out";
&&&&&&&&&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&#endregion
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (SocketException se)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&SockErrorStr = se.ToString();
&&&&&&&&&&&&&&&&return false;
&&&&&&&&&&&&}
&&&&&&&&///
&&&&&&&&/// 同步发送
&&&&&&&&///
&&&&&&&&///
&&&&&&&&///
&&&&&&&&public static bool SendData(string dataStr)
&&&&&&&&&&&&bool result = false;
&&&&&&&&&&&&if (dataStr == null || dataStr.Length < 0)
&&&&&&&&&&&&&&&&return result;
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&byte[] cmd = Encoding.Default.GetBytes(dataStr);
&&&&&&&&&&&&&&&&int n = theSocket.Send(cmd);
&&&&&&&&&&&&&&&&if (n < 1)
&&&&&&&&&&&&&&&&&&&&result = false;
&&&&&&&&&&&&}
&&&&&&&&&&&&catch (Exception ee)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&SockErrorStr = ee.ToString();
&&&&&&&&&&&&&&&&result = false;
&&&&&&&&&&&&}
&&&&&&&&&&&&return result;
三、源码下载
阅读(25068) | 评论(1) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
哥们,这篇文章写得有深度、很实用,顶一个。
请登录后评论。让人头疼的Socket断开Disconnect方法,前面是基于SocketAsyncEventArgs的操作。
[问题点数:50分]
让人头疼的Socket断开Disconnect方法,前面是基于SocketAsyncEventArgs的操作。
[问题点数:50分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。socket.io 如何准确判断server与client之间断开连接 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
1、如果client端断开网络,我在Server端如何准去判断client端断开连接了!!!!
2、disconnect不管用,只有在client端关闭浏览器的时候 ,server端才能检测到。
好纠结 !麻烦遇到这样问题的告诉一下解决方案 qq:
文档中说是在transport连接 (就是TCP)Close后再等一段时间(15秒,可配置)释放资源。我们知道一般TCP 不会轻易Close,网站没数据,可能连接一直存在着。
所以有两种思路,一个是自己在在Scoket.io的业务层设置定时器,超过一段时间无业务数据,释放socket.io的资源。另一种就是把TCP连接超时时间设短,不过要注意socket.io的socket不是node.js的socket,可以参考以下代码:
io.sockets.on(‘connection’, function (socket) {
socket.manager.transports[].socket.setTimeout(15000);
如果client关闭后,大约15+15秒之后会释放资源。
这样做还是达不到我想要的效果! 比如 聊天室,如果有一个人的网线断了(不是关闭浏览器),我在服务器端怎么监听?
他掉了了我就不用给他发消息?
socket.io就没有自己的api event?
我找了好久就是没有,自己想的思路就是在发送消息的时候发一个字节给client端 如果client端有反应 就表示在 !但是这样不是我想要的结果!我想的是server端主动监听,实时返回client断开了,而不是等我需要发发送消息的时候才去验证client的端是否在线!
你先要明确你所谓“client断开了”的含义。
socket.io也并不知道你需要什么逻辑?event有connection和disconnect就足够了。
之前已经说过了,所谓用户是否在线,是应用层的,比如聊天室的是否在线标准是看用户是否有输入。
而对于socket.io是transport层没断,它就一直给你保持通路。因为实际上transport是通的,那么断开socket.io连接的工作由client或server端负责都可以。一旦断socket.io的连接,实际上是断transport层的连接,对端也可以检测到。
以下例子是依据是否Server端根据是否接受到client端的数据判断是否“client断开了”,, 由client端负责断连接。
== Server Side
var app = require(‘http’).createServer(handler)
, io = require(‘’).listen(app)
, fs = require(‘fs’)
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + ‘/index.html’,
function (err, data) {
if (err) {
res.writeHead(500);
return res.end(‘Error loading index.html’);
res.writeHead(200);
res.end(data);
function Client(socket) {
var self =
this.socket =
this.timeoutProc = function timeoutProc() {
console.log(&#x27;timeouted&#x27;);
self.socket.emit(&#x27;DisconnectReq&#x27;);
this.datain = function(data) {
clearTimeout(this.timeout);
&#x2F;&#x2F;......... Your processing
this.timeout = setTimeout(this.timeoutProc, 15000);
this.timeout = setTimeout(this.timeoutProc, 15000);
io.sockets.on(‘connection’, function (socket) {
var client = new Client(socket);
socket.emit(‘news’, { hello: ‘world’ });
socket.on(‘my other event’, function (data) {
console.log(data);
client.datain(data);
socket.on(‘disconnect’, function(){
console.log(‘receive disconnect event’);
== Client Side
&script src="/socket.io/socket.io.js"&&/script&
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
socket.on('DisconnectReq', function() {
socket.disconnect();
网线断的情况,socket.manager.transports[].socket.setTimeout(15000);应该能检测。会触发transport层的close–& socket.io的disconnect事件
刷新浏览器也是会触发disconnect事件的,所以个人觉得用延时的方法去判断比较好。
socket.on &#x27;disconnect&#x27;, -&
setTimeout -&
refresh_online()
empty_room()
我原来也发现不好使,不过貌似这样就行了
可以试试哈
10毫秒?太短了吧?如果客户端是因为刷新浏览器的话你也会认为是短线了吧?
对啊 刷新就断线,不过会直接再次连接上啊
所以个人觉得应该加入防抖的机制,这样就不会刷新一下就提示下线,然后又上线。
嗯嗯 也是 当时没多想 哈哈 3Q
呵呵,不客气,相互学习
(●’?’●)??
请教下你这里的 empty_room()是什么啊?
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的

我要回帖

更多关于 socket断开连接 的文章

 

随机推荐