I have a problem with connection handling in TCP Client socket.
This code should connect to localhost at 4444 port and listening for all incoming data from this TCP Server.
I need to write connection handling for this. For example if while attempting to connect server is not responding it should trying to connect again, or if connection is ready and after receiving some data TCP server will close the connection TCP client should try to reconnect again.
Can anyone help me with this problems
Here is what I have in this moment
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 :(得分:0)
What you want is a way to keep retrying the connection if it fails. And if there is an exception during a read, you want to see if we're still connect and if not then re-connect. I added a loop in the Connect() method to retry the connect after waiting for 1 second.
In the receive callback, I put a try/catch and if there is an exception I will go back to the Connect() method to retry the connection.
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);
}
}