2016-02-12 4 views
0

У меня возникла проблема с обработкой подключения в TCP-клиентском сокете.TCP Socket client Async - обработка подключения

Этот код должен подключаться к локальному хосту на 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

Uhm ... для будущих пользователей (и, возможно, для аскер), может быть сложно ответить только на код, особенно одна из этой длины. Не могли бы вы добавить какое-то объяснение того, что вы изменили, желательно указать, где OP поступил неправильно, и что вы его исправить? – Serlite

+0

@Serlite конечно, проблема. Я только что изменил класс OPs, изменив несколько строк. Я прокомментирую – Mangist

+0

@Mangist Я попробовал ваш метод этим решением заморозить Unity, если TCP-сервер не отвечает. Является ли это возможным? или я выполняю его неправильно? – seek

Смежные вопросы