1. TcpClient.Connected: 属性获取截止到最后一次 I/O 操作时的 Client 套接字的连接状态。
2. TcpClient.Client.Connected: 属性获取截止到最后的 I/O 操作时 Socket 的连接状态。Connected 属性的值反映最近操作时的连接状态。 如果您需要确定连接的当前状态,请进行非阻止、零字节的 Send 调用。 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;否则,该套接字不再处于连接状态。(MSDN上还有一段代码)
3. TcpClient.Available: 如果远程主机处于关机状态或关闭了连接,Available 可能会引发 SocketException。
4. TcpClient.Client.Available: 如果远程主机处于关机状态或关闭了连接,则 Available 会引发 SocketException。
5. Socket.Poll:  http://msdn.microsoft.com/zh-cn/library/vstudio/system.net.sockets.socket.poll(v=vs.100).aspx (主要看Mode为SelectRead时Poll的返回值)
6. 有网友提供如下方法:

if (s.Poll(-1, SelectMode.SelectRead)){   int nRead = s.Receive();   if (nRead == 0)   {     //socket连接已断开   }}
接关闭软件! 不能检测出对方断开连接(tcpClient.Close)!
2. 根据TcpClient.Client.Available后面的说明做验证,发现当对方关闭了连接后获取Available还是不回引发异常!
3. 经测试,上述网友提供的方法倒是可以检测 物理网络不通、对方关闭套接字 !但是网上有人说,即使网络正常nRead也可能为0!这种情况我还没有遇到过
不知道Client端已經不存在了, 笨笨的繼續傳遞資料給Client(是我笨吧…Orz)
當然會導致程式發生Exception……….
Server真的會不知道嗎~~會他當然會知道 但是預設為兩小時後[1]~這早就發生Exception…
經過[1]中發現, 原來可以設定 Keep-Alive來保持Socket長連接, 並且偵測網路異常拋出Exception
當Client端發生不正常斷線時, Server端將會立刻知道~~~
Keep-Alive使用方法寫在Comment裡嚕~ 這裡紀錄一下
 
using System.Net.Sockets;
using System.Net;
public class ServerSocketObject
{
    public  Socket ClientToServerSocket;
    private Socket ListenSocket;
    private IPEndPoint ServerIPEndPoint;
    public ManualResetEvent BeginAccpetControl=new ManualResetEvent(false);
    //==========================
    private Boolean IsBeginAccept = true ;
    public List<byte> Reply_Message = new List<byte>();
    public ServerSocketObject()
    {
        string LocalIP = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();
        ServerIPEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 2266);
        ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        ListenSocket.Bind(ServerIPEndPoint);
        ListenSocket.Listen(1);  //ip pool 設為 1
        ListenSocket.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 1000, 1000), null); 
        //將這個Socket使用<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">keep</b>-alive來保持長連線
        //KeepAlive函數參數說明: onOff:是否開啟<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">Keep</b>-Alive(開 1/ 關 0) ,
        //keepAliveTime:當開啟<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">keep</b>-Alive後經過多久時間(ms)開啟偵測
        //keepAliveInterval: 多久偵測一次(ms)
    }
    private byte[] KeepAlive(int onOff, int keepAliveTime, int keepAliveInterval)
    {
        byte[] buffer = new byte[12];
        BitConverter.GetBytes(onOff).CopyTo(buffer, 0);
        BitConverter.GetBytes(keepAliveTime).CopyTo(buffer, 4);
        BitConverter.GetBytes(keepAliveInterval).CopyTo(buffer, 8);
        return buffer;
    }
    public void BeginAccept()
    {
        while (IsBeginAccept)
        {
            BeginAccpetControl.Reset();
            ListenSocket.BeginAccept(new AsyncCallback(BeginAcceptCallBack), ListenSocket);
            BeginAccpetControl.WaitOne(); //等待Clinet...
        }
        //===================
    }
    private void BeginAcceptCallBack(IAsyncResult state)
    {
        Socket Listener = (Socket)state.AsyncState;
        ClientToServerSocket = Listener.EndAccept(state); //Client連線成功
        ClientToServerSocket.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReceivedCallBack), ClientToServerSocket); 
        //連線成功後 開始接收Server所傳遞的資料
        BeginAccpetControl.Set();
    }
    private void ReceivedCallBack(IAsyncResult ar)
    {
        Socket state = (Socket)ar.AsyncState;
        if (state.Connected == true)
        {
            try
            {
                int bytesRead = state.EndReceive(ar);
                if (bytesRead > 0) //當 bytesRead大於0時表示Server傳遞資料過來 等於0時代表Client"正常"斷線
                {
                    for (int num = 0; num < bytesRead; num++)
                    {
                        Reply_Message.Add(buffer[num]); //收集資料
                    }
                    state.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReceivedCallBack), ClientToServerSocket);
                }
                else
                {
                    //處理Client端"正常"斷線的事件
                }
            }
            catch (Exception ee)
            {
                //這裡就是當設定好<b style="background: rgb(255, 102, 255); color: rgb(0, 0, 0);">Keep</b>-alive後, 假設Clinet端發生"不正常斷線(網路異常)"時, 將會
                //跑進來這個Exception裡,再加以處理
                state.Shutdown(SocketShutdown.Both);
                state.Close();
            }
        }
        else
        {
            IsConntect = false;
            state.Close();
        }
    }
}

Clinet端不正常斷線時, Server端竟然不知道相关推荐

  1. 7开启uasp协议_Dubbo-go 源码笔记(一)Server 端开启服务过程

    导读:随着微服务架构的流行,许多高性能 rpc 框架应运而生,由阿里开源的 dubbo 框架 go 语言版本的 dubbo-go 也成为了众多开发者不错的选择.本文将介绍 dubbo-go 框架的基本 ...

  2. Dubbo-go 源码笔记(一)Server 端开启服务过程

    作者 | 李志信 dubbo-go 源码:https://github.com/apache/dubbo-go 导读:随着微服务架构的流行,许多高性能 rpc 框架应运而生,由阿里开源的 dubbo ...

  3. Hadoop中RPC机制详解之Server端

    2019独角兽企业重金招聘Python工程师标准>>> Hadoop 中 RPC 机制详解之 Client 端 1. Server.Listener RPC Client 端的 RP ...

  4. Drcom账户管理Server端解说

    https://www.github.com/xiyouMc 首先今天要讲的是针对Drcom查询账户URL的解析和抓取数据.    Drcom是大学生宿舍上网普遍使用的联网client,然而对于自己账 ...

  5. socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字

    这里的"通讯"加上了引号,是因为实际上所有的socket都有通讯的功能,只是在我们的例子中,之前那个socket只负责listen,而这个socket负责接受信息并echo回去. ...

  6. Linux下Socket编程之TCP Server端

    一.建模 绝大部分关于socket编程的教程总是从socket的概念开始讲起的.要知道,socket的初衷是个庞大的体系,TCP/IP只是这个庞大体系下一个很小的子集,而我们真正能用上的更是这个子集中 ...

  7. 详解zabbix安装部署(Server端篇)

    Linux下常用的系统监控软件有Nagios.Cacti.Zabbix.Monit等,这些开源的软件,可以帮助我们更好的管理机器,在第一时间内发现,并警告系统维护人员. 今天开始研究下Zabbix,使 ...

  8. elasticsearch源码分析之search模块(server端)

    elasticsearch源码分析之search模块(server端) 继续接着上一篇的来说啊,当client端将search的请求发送到某一个node之后,剩下的事情就是server端来处理了,具体 ...

  9. linux下的c socket编程(4)--server端的继续研究

    linux下的C socket编程(4) 延长server的生命周期: 在前面的一个个例子中,server在处理完一个链接之后便会立即结束掉自己,然而这种server并不科学,server因该使能够一 ...

最新文章

  1. android资料整理
  2. 【PHPWord】TextRun
  3. 闪回之 Flashback Data Archive
  4. 5道不一样的Python基础题练习题,很有难度
  5. PyTorch基础(11)----- torch.sum()方法
  6. javascript事件详细说明
  7. 多用户操作git“远程仓库“(本地)
  8. C while 循环
  9. 夏门大学的计算机专业排第几,厦门大学最好重点的专业在全国排名具体情况
  10. AndroidStudio安卓原生开发_Activity的启动模式standard和一部分singleTop启动模式---Android原生开发工作笔记86
  11. lg g7 刷机 救砖 root
  12. apr_thread使用内存之谜
  13. java 正则表达式匹配冒号_用于匹配与冒号连接的单词对的正则表达式
  14. 预应力内力计算时作用机理(纠结好久的问题orz)
  15. 自己动手编译Android源码(超详细)
  16. mysql自定义变量比较大小_MySQL 自定义变量@ 常用案例
  17. 全球注意力缺陷多动障碍(ADHD)市场规模2021年大约为796亿元(人民币),预计2028年将达到1259亿元
  18. 「前端进阶」JS中的内存管理
  19. 51单片机四位数码管的使用方法
  20. 多人交互与体感游戏开发相关技术说明

热门文章

  1. CnOpenData全国兴趣点(POI)数据
  2. LINK1104:无法打开文件“shell32.lib”
  3. 一个仿携程的移动端网站
  4. CSS3实现针线缝合效果
  5. WebRTC服务器理论铺垫(六):OpenSSL协议,DTLS协议,RTP协议和SRTP协议
  6. GB28181协议实现系列之----IPC音视频PS封装(5)
  7. 练习:ESP8266 + Blinker 远程启动空调
  8. 简述UIAlertView的属性和用法
  9. 大学生及今后的java之路
  10. 选择卡农线平衡输出还是RCA输出,试过才知道差别