2016-02-12 145 views
0

我在TCP客户套接字中的连接处理有问题。TCP套接字客户端异步 - 连接处理

此代码应连接到4444端口的本地主机,并侦听来自此TCP服务器的所有传入数据。

我需要为此编写连接处理。例如,如果尝试连接服务器时没有响应,它应该尝试重新连接,或者如果连接已准备就绪,并且在接收到某些数据后TCP服务器将关闭连接,则TCP客户端应尝试重新连接。

谁能帮我解决这个问题

以下是我在这一刻

using UnityEngine; 
using System.Collections; 
using System; 
using System.Net; 
using System.Net.Sockets; 

public class TCPClientNew : MonoBehaviour { 

    private Socket _clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 
    private byte[] _recieveBuffer = new byte[8142]; 

    private void StartClient() 
    { 
     try 
     { 
      _clientSocket.Connect(new IPEndPoint(IPAddress.Loopback,4444)); 
     } 
     catch(SocketException ex) 
     { 
      Debug.Log(ex.Message); 

      // Try to reconnect ?? TODO 
     } 
     Debug.Log ("connected"); 

     _clientSocket.BeginReceive(_recieveBuffer,0,_recieveBuffer.Length,SocketFlags.None,new AsyncCallback(ReceiveCallback),null); 

    } 

    private void ReceiveCallback(IAsyncResult AR) 
    { 
     //Check how much bytes are recieved and call EndRecieve to finalize handshake 
     int recieved = _clientSocket.EndReceive(AR); 

     if(recieved <= 0) 
      return; 

     //Copy the recieved data into new buffer , to avoid null bytes 
     byte[] recData = new byte[recieved]; 
     Buffer.BlockCopy(_recieveBuffer,0,recData,0,recieved); 


     //Processing received data 
     Debug.Log (System.Text.Encoding.ASCII.GetString(recData)); 



     //Start receiving again 
     _clientSocket.BeginReceive(_recieveBuffer,0,_recieveBuffer.Length,SocketFlags.None,new AsyncCallback(ReceiveCallback),null); 
    } 

    private void SendData(byte[] data) 
    { 
     SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs(); 
     socketAsyncData.SetBuffer(data,0,data.Length); 
     _clientSocket.SendAsync(socketAsyncData); 
    } 

    void Start() 
    { 
     StartClient(); 
    } 
} 

回答

0

你需要的是不断重试连接,如果它失败的方式。如果在读取过程中出现异常,您想查看我们是否仍然连接,如果没有,请重新连接。我在Connect()方法中添加了一个循环,在等待1秒后重新尝试连接。

在接收回调中,我放了一个try/catch,如果有异常,我将回到Connect()方法重试连接。

public class TCPClientNew 
{ 

    private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    private byte[] _recieveBuffer = new byte[8142]; 

    private void Connect() 
    { 
     bool isConnected = false; 

     // Keep trying to connect 
     while (!isConnected) 
     { 
      try 
      { 
       _clientSocket.Connect(new IPEndPoint(IPAddress.Loopback, 4444)); 
       // If we got here without an exception we should be connected to the server 
       isConnected = true; 
      } 
      catch (SocketException ex) 
      { 
       Debug.Log(ex.Message); 

       // Wait 1 second before trying to connect again 
       Thread.Sleep(1000); 
      } 
     } 

     // We are now connected, start to receive 
     _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null); 
    } 

    private void ReceiveCallback(IAsyncResult AR) 
    { 
     //Check how much bytes are recieved and call EndRecieve to finalize handshake 
     try 
     { 
      int recieved = _clientSocket.EndReceive(AR); 

      if (recieved <= 0) 
       return; 

      //Copy the recieved data into new buffer , to avoid null bytes 
      byte[] recData = new byte[recieved]; 
      Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved); 

      //Start receiving again 
      _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null); 
     } 
     catch (SocketException ex) 
     { 
      Debug.Log(ex.Message); 

      // If the socket connection was lost, we need to reconnect 
      if (!_clientSocket.Connected) 
      { 
       Connect(); 
      } 
      else 
      { 
       //Just a read error, we are still connected 
       _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null); 
      } 
     } 
    } 

    private void SendData(byte[] data) 
    { 
     SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs(); 
     socketAsyncData.SetBuffer(data, 0, data.Length); 
     _clientSocket.SendAsync(socketAsyncData); 
    } 
} 
+0

呃......代码唯一的答案,特别是这个长度之一,对未来的用户(以及潜在的提问者)来说可能很难遵循。你能否给我添加一些你改变的解释,最好是指出OP出错的地方,你做了什么修复? – Serlite

+0

@Serlite肯定,问题。我只是通过改变几行来修改OPs类。我会评论 – Mangist

+0

@Mangist如果TCP服务器没有响应,我尝试了通过这个解决方案冻结Unity的方法。可能吗?或者我以错误的方式执行它? – seek