如何确定是否tcp的连接或不? [英] How to determine if the tcp is connected or not?

查看:349
本文介绍了如何确定是否tcp的连接或不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的TcpClient对象,我想,以确定它是否连接与否。 我使用的TcpClient连接的属性,但它返回最后一次操作的状态。所以它不是很有用。

I have tcpclient object and i want to determine if it's connected or not. i use connected property of tcpclient but it returns the state of last operation. so its not useful.

然后我用这个code:

then i use this code :

bool flag;
flag = (tcp.Client.Poll(10000, SelectMode.SelectWrite));

 if( tcp.Client.Poll( 0, SelectMode.SelectRead ) )
 {
   byte[] buff = new byte[1];
   if( tcp.Client.Receive( buff, SocketFlags.Peek ) == 0 )
   {
     flag = false;
   }
 }

但它不能正常工作。

but it does not work properly.

你知道吗?

这是我的code在服务器端:

this is my code in server side :

   private ArrayList _ClientList = new ArrayList();

   public ClsServer(int port)
    {
        _TCPListener = new TcpListener(IPAddress.Any, port);
        _TCPListener.Start();

        Thread ListenThread = new Thread(new ThreadStart(ListenForClients));
        ListenThread.IsBackground = true;
        ListenThread.Start();
    }

    private void ListenForClients()
    {            
        while (true)
        {
            //blocks until a client has connected to the server
            TcpClient client = this._TCPListener.AcceptTcpClient();
            client.ReceiveTimeout = 0;

            //create a thread to handle communication with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            clientThread.IsBackground = true;
            clientThread.Start(client);
        }
    }

    private void HandleClientComm(object client)
    {
        try
        {
            TcpClient tcpClient = (TcpClient)client;               
            AddObject(tcpclient);

            int bytesRead;
            string message = "";
            byte[] RecievedPack = new byte[1024 * 1000];

            NetworkStream clientStream = tcpClient.GetStream();
            while (true)
            {
                bytesRead = 0;
                try
                {
                    ////blocks until a client sends a message
                    bytesRead = clientStream.Read(RecievedPack, 0, RecievedPack.Length);
                    int Len = BitConverter.ToInt32(RecievedPack, 0);
                    message = UTF8Encoding.UTF8.GetString(RecievedPack, 0, Len);
                }
                catch (Exception er)
                {
                    //When Client is disconnected
                    if (er.GetType() == typeof(IOException))
                    {
                        RemoveObject(client);
                        break;
                    }
                }                   
                //message has successfully been received                          
               // do something
            }

            RemoveObject(client);
        }
        catch(Exception e)
        {
           // RemoveObject(client);
        }
    }

    private void AddObject(object obj)
    {            
        int totalcount, index;
        totalcount = _ClientList.Count;
        index = 0;
        while (index < totalcount)
        {
            TcpClient alcobj = (TcpClient)_ClientList[index];
            try
            {
                if (IPAddress.Equals(((IPEndPoint)alcobj.Client.RemoteEndPoint).Address,
                   ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address))
                {
                    _ClientList.Remove(alcobj);
                    break;
                }
                index++;
            }
            catch (Exception er)
            {
                if (er.GetType() == typeof(ObjectDisposedException))
                    RemoveObject(alcobj);
            }
            finally
            {
                totalcount = _ClientList.Count;
            }
        }            
         _ClientList.Add(obj);             
    }

    private void RemoveObject(object obj)
    {            
        if (_ClientList.IndexOf(obj) > -1)
        {
            _ClientList.Remove(obj);
            SendClientState(IP, false);
        }         
    }

和这是在客户端:

    public bool IsConnected
    {           
            try
            {
                if (_TcpClient != null && _TcpClient.Client != null && _TcpClient.Client.Connected)
                {
                    // Detect if client disconnected
                    if (_TcpClient.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] buff = new byte[1];
                        if (_TcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
                        {
                            // Client disconnected
                            return false;
                        }
                        else
                        {
                            return true;
                        }
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
    }

   private void clsClient()
   {
          if(!IsConnected()) 
          {
                  Connecttoserver()
           }
    }

    private void ConnectToServer()
    {
        try
        {
            NetworkStream _NetworkStream = _TcpClient.GetStream();
            byte[] _RecievedPack = new byte[1024 * 1000];
            string _Message = string.Empty;
            int _BytesRead;
            int _Length;

            while (true)
            {
                _BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
                _Length = BitConverter.ToInt32(_RecievedPack, 0);
                _Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);

                if (_BytesRead != 0)
                {
                    if (OnReceive != null)
                        // do something

                    _NetworkStream.Flush();
                }
            }
        }
        catch (Exception exp)
        {
            // do something 
        }
    }

在客户端,IsConnected()始终返回false并试图connecttoserver,所以服务器监听器总是尝试添加客户端列表中的

in client side, IsConnected() always return false and try to connecttoserver, so the server listener always try to add the client in a list

推荐答案

使用这种code相反,我已经测试了它,并在实际生产软件中使用它:

Use this code instead, I have tested it and using it in real production software:

public bool IsConnected
{
    get
    {
        try
        {
            if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected)
            {
               /* pear to the documentation on Poll:
                * When passing SelectMode.SelectRead as a parameter to the Poll method it will return 
                * -either- true if Socket.Listen(Int32) has been called and a connection is pending;
                * -or- true if data is available for reading; 
                * -or- true if the connection has been closed, reset, or terminated; 
                * otherwise, returns false
                */

                // Detect if client disconnected
                if (_tcpClient.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] buff = new byte[1];
                    if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
                    {
                        // Client disconnected
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }
        catch
        {
            return false;
        }
    }
}

编辑:但是你不能仅仅依靠检查连接,如果真的进行,因为它的返回连接的状态,在这个时候财产执行,例如你检查后 IsConnected 键,返回true,而当你在沟通的中间,连接可能丢失在那里!我们只是用它摆在首位,以减少故障的可能性,所以,你不得不将整个通信在一个try / catch和期望的连接,在任何时候丢了!

However you can't rely on just checking the connection and if true proceed, because it returning the status of connection at time this property executed, for instance after you check IsConnected and it returns true, and while you are in the middle of communication, the connection maybe lost there! we just use it in the first place to reduce the probability of failure, So you have to wrap the whole communication in a try/catch and expect the connection to be lost at any time!

这篇关于如何确定是否tcp的连接或不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆