zoukankan      html  css  js  c++  java
  • C#服务端判断客户端socket是否已断开的方法

    刚开始,用Socket类的Connected属性来实现,却发现行不通,connected只表示  是在上次 还是 操作时连接到远程主机。如果在这之后[连接的另一方]断开了,它还一直返回true, 除非你再通过socket来发送数据。所以通过个属性来判断是行不通的!
     后来有人说可以用Socket.Available属性来判断,Socket.Available表示获取已经从网络接收且可供读取的数据量。

    msdn中说:如果[连接的另一方]断开了,它就会抛出异常。然而,这个BUG报告(http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/)却指出:msdn的说法并不完全正确,这个属性只有在少数情况下才抛出异常。所以,这一招还是行不通!

    最后使用socket.Poll()方法来完成实现,此方法是确定socket的状态。看下面的代码:

    服务端代码: 

    class Program
    
        {
            private static List<Socket> list=new List<Socket>(); 
            static void Main(string[] args)
            {            
                Timer timer=new Timer(1000);
                timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
                timer.Start();
                Thread thread = new Thread(Listener);
                thread.Start();
            }
    
            //每秒服务端向客户端推送
    
            static void timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                if (list.Count > 0)
                {
                    for (int i = list.Count-1; i >=0; i--)
                    {
                        
                        string sendStr = "Server Information";
                        byte[] bs = Encoding.ASCII.GetBytes(sendStr);
                        if (list[i].Poll(1000, SelectMode.SelectRead)) 
                //SelectMode.SelectRead表示,如果已调用 并且有挂起的连接,true。             //- 或 - 如果有数据可供读取,则为 true。- 或 - 如果连接已关闭、重置或终止,则返回 true(此种情况就表示若客户端断开连接了,则此方法就返回true); 否则,返回 false
    { list[i].Close();
    //关闭socket list.RemoveAt(i);//从列表中删除断开的socke continue; } list[i].Send(bs, bs.Length, 0); } } } public static void Listener() { int port = 11000; string host = "192.168.7.36"; /**/ ///创建终结点(EndPoint) IPAddress ip = IPAddress.Parse(host);//把ip地址字符串转换为IPAddress类型的实例 IPEndPoint ipe = new IPEndPoint(ip, port);//用指定的端口和ip初始化IPEndPoint类的新实例 /**/ ///创建socket并开始监听 Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket对像,如果用udp协议,则要用SocketType.Dgram类型的套接字 s.Bind(ipe);//绑定EndPoint对像(2000端口和ip地址) s.Listen(10);//开始监听 Console.WriteLine("等待客户端连接"); while (true) { /**/ ///接受到client连接,为此连接建立新的socket,并接受信息 list.Add(s.Accept());//为新建连接创建新的socket Console.WriteLine("建立连接"); string recvStr = ""; byte[] recvBytes = new byte[1024]; int bytes; bytes = list[list.Count-1].Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); /**/ ///给client端返回信息 Console.WriteLine("server get message:{0}", recvStr);//把客户端传来的信息显示出来 string sendStr = "ok!Client send message successful!"; byte[] bs = Encoding.ASCII.GetBytes(sendStr); list[list.Count-1].Send(bs, bs.Length, 0);//返回信息给客户端 //temp.Close(); } s.Close(); } }

    转自:http://hi.baidu.com/jack1865/item/3dcba2d3b0e2e29932db904d

  • 相关阅读:
    HDU 5585 Numbers
    HDU 3308 LCIS
    POJ 2991 Crane
    POJ 1436 Horizontally Visible Segments
    POJ 3667 Hotel
    HaiHongOJ 1003 God Wang
    【SDOI 2008】 递归数列
    5月19日省中提高组题解
    【HDU 1588】 Gauss Fibonacci
    【POJ 3233】Matrix Power Series
  • 原文地址:https://www.cnblogs.com/cuisir/p/8522680.html
Copyright © 2011-2022 走看看