[Unity] Simple TCP

1. Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;

public delegate void ConnectCallBack();
public delegate void TCPRecvCallBack(string msg);

public class AnTCP
{
    public enum TCPMode
    {
        Client,//客户端
        Server//服务端
    }

    private int TcpPort;
    private Socket TcpSocket;
    private Socket TcpClient;
    private EndPoint ServerPoint;
    private TCPMode Mode;
    //
    private Thread OpenThread;//监听(链接)线程
    private Thread RecvThread;//接收线程

    //call back
    private ConnectCallBack ConnectCall;
    private TCPRecvCallBack RecvCallBack;//回调函数

    public AnTCP()
    {
        TcpPort = 0;
    }

    public bool Open(TCPMode _mode,int _port,string _ip, ConnectCallBack _call)
    {
        Mode = _mode;
        TcpPort = _port;
        TcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        if(Mode == TCPMode.Client)
        {
            ServerPoint = new IPEndPoint(IPAddress.Parse(_ip), TcpPort);
        
            if (OpenThread != null)
            {
                OpenThread.Abort();
                OpenThread.Interrupt();
                OpenThread = null;
            }
            OpenThread = new Thread(OnConnectToServer);
            OpenThread.Start();
            //
            ConnectCall = _call;
        }
        else if(Mode == TCPMode.Server)
        {
            //绑定端口和网络地址
            ServerPoint = new IPEndPoint(IPAddress.Parse(_ip), TcpPort);
            TcpSocket.Bind(ServerPoint);
            //最大连接数
            TcpSocket.Listen(5);
            //开启线程
            if(OpenThread != null)
            {
                OpenThread.Abort();
                OpenThread.Interrupt();
                OpenThread = null;
            }
            OpenThread = new Thread(OnWaitForClient);
            OpenThread.Start();
            //
            ConnectCall = _call;
        }
        return true;
    }
    public void Close()
    {
        if (OpenThread != null)
        {
            OpenThread.Abort();
            OpenThread.Interrupt();
            OpenThread = null;
        }
        if (RecvThread != null)
        {
            RecvThread.Abort();
            RecvThread.Interrupt();
            RecvThread = null;
        }
        if (TcpSocket != null)
        {
            TcpSocket.Close();
        }
        if (TcpClient!=null)
        {
            TcpClient.Close();
        }
       
    }
    public bool Send(string msg)
    {
        if (TcpSocket == null) return false;
        byte[] sendData = Encoding.ASCII.GetBytes(msg);
        if (Mode == TCPMode.Client)
            TcpSocket.Send(sendData);
        else if (Mode == TCPMode.Server)
            TcpClient.Send(sendData);
            return true;
    }

    public void StartRecv(TCPRecvCallBack _call)
    {
        RecvCallBack = _call;
    }

    private void OnConnectToServer()
    {
        while (true)
        {
            try
            {
                TcpSocket.Connect(ServerPoint);

                if (RecvThread != null)
                {
                    RecvThread.Abort();
                    RecvThread.Interrupt();
                    RecvThread = null;
                }
                RecvThread = new Thread(ClientReceive);
                RecvThread.Start();

                if (ConnectCall != null)
                {
                    ConnectCall();
                }

                OpenThread.Abort();
                return;
            }
            catch (Exception e)
            {

            }

        }
    }
    private void OnWaitForClient()
    {
        while(true)
        {
            try
            {
                TcpClient = TcpSocket.Accept();

                if (RecvThread != null)
                {
                    RecvThread.Abort();
                    RecvThread.Interrupt();
                    RecvThread = null;
                }
                RecvThread = new Thread(ServerReceive);
                RecvThread.Start();

                if (ConnectCall != null)
                {
                    ConnectCall();
                }
            }
            catch (Exception e)
            {

            }
            
        }
    }

    private void ClientReceive()
    {
        while (true)
        {
            try
            {
                byte[] recvData = new byte[1024];
                //接收
                int recvLen = TcpSocket.Receive(recvData);
                if (recvLen > 0)
                {
                    string data = Encoding.ASCII.GetString(recvData, 0, recvLen);
                    if (RecvCallBack != null)
                    {
                        RecvCallBack(data);
                    }
                }
            }
            catch (Exception e)
            {

            }
        }
    }

    private void ServerReceive()
    {
        while (true)
        {
            try
            {
                byte[] recvData = new byte[1024];
                //接收
                int recvLen = TcpClient.Receive(recvData);
                if (recvLen > 0)
                {
                    string data = Encoding.ASCII.GetString(recvData, 0, recvLen);
                    if (RecvCallBack != null)
                    {
                        RecvCallBack(data);
                    }
                }
            }
            catch (Exception e)
            {

            }
        }
    }
}

Two, use

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Controller : MonoBehaviour
{
    public Text Log;

    private AnTCP TCP;
    private List<string> SockOrders;
    // Start is called before the first frame update
    void Start()
    {
        TCP = new AnTCP();
        TCP.Open(AnTCP.TCPMode.Server, 9000, "127.0.0.1", OnConnected);

        SockOrders = new List<string>();
    }

    // Update is called once per frame
    void Update()
    {
        if(SockOrders.Count!=0)
        {
            Log.text = SockOrders[0];
            SockOrders.RemoveAt(0);
        }
    }
    void OnApplicationQuit()
    {
        TCP.Close();
    }
    private void OnConnected()
    {
        TCP.Send("Hello");
        TCP.StartRecv(OnRecved);
    }

    private void OnRecved(string msg)
    {
        SockOrders.Add(msg);
    }
}

3. Remarks

1. Only 1-to-1 link is supported, and the receiving and sending of the server are the last ones
2. Use ASCII

Guess you like

Origin blog.csdn.net/qq_36251561/article/details/128577749