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. java set如何判断重复_set 怎么用iterator()方法来区分重复与否
  2. gentoo doc web site
  3. java引用传递106_(转载)java的值传递与引用传递
  4. 堪称艺术品级的应用开发框架,Abp有望超越Spring?
  5. 两个大屏可视化案例的布局与实现
  6. 现在学java的都是傻子?
  7. C# 中的 ConfigurationManager类引用方法应用程序配置文件App.config的写法
  8. java并发线程池---了解ThreadPoolExecutor就够了
  9. 一文读懂特征值分解EVD与奇异值分解SVD
  10. python画散点图分布-python中画散点图
  11. Pycharm中配置.ui转.py文件;.qrc文件转.py文件和Qtcreator
  12. Android开发什么该做、什么不该做,你真的知道吗?
  13. 到底什么是上下文(Context)
  14. 热爱生活阳光自信才能让自己快乐
  15. 计算机睡眠状态如何恢复,显示器进入睡眠状态怎么解决
  16. SAP中SD交货与WM下架功能的集成应用
  17. 【能效管理】关于学校预付费水电系统云平台应用分析介绍
  18. 搞一下整车以太网技术 | A1 整车以太网技术概述
  19. mysql定时任务每天凌晨三点钟醒来_常常凌晨三四点醒来是怎么回事?遇到这事要警惕了...
  20. CLRS 16.1活动选择问题

热门文章

  1. Mac版R语言(四):pacman包——在R语言工程中一次性下载安装、导入多个包的方法
  2. PHP封装curd,ThinkPHP5.0的模型CURD创建Create操作
  3. HTML+CSS系列教程
  4. 为了分析最近热点电影的观众爱好取向,爬取《镇魂》微博评论数据
  5. 802.11--802.11g协议
  6. dnf搬砖搭建无盘服务器,DNF:工作室搬砖256开,大批量操作有苦难言,工作室:只为了谋生...
  7. JavaScript之BOM
  8. pycharm pandas 经典报错 pandas.core.base.SpecificationError: nested renamer is not supported
  9. SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising 论文解读
  10. 为什么计算机处理打不开,为什么电脑ps安装成功打不开怎么办