[Unity]简单TCP

该文章介绍了一个在Unity3D中用C#编写的TCP网络通信类AnTCP,支持客户端和服务端模式。类中包含连接、发送、接收和关闭网络连接的方法,并使用线程处理异步操作。此外,它还定义了连接成功和数据接收的回调函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、代码

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)
            {

            }
        }
    }
}

二、使用

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

三、备注

1.仅支持1对1链接,服务端接收和发送都是最后那个
2.使用ASCII

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值