首页 文章

TCP套接字客户端异步 - 连接处理

提问于
浏览
0

我在TCP客户端套接字中遇到连接问题 .

此代码应连接到4444端口的localhost并侦听来自此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 ();
    }
}

1 回答

  • 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);
        }
    }
    

相关问题