2016-02-12 151 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