实现客户端的网络不影响主线程且随时与服务器通信

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
//网络管理器(单例模式)
public class NetMgr : MonoBehaviour
{
    private static NetMgr instance;

    //用于发送消息的队列 公共容器 主线程往里边放 发送线程从里边取
    private Queue<string> sendMgsQueue = new Queue<string>();
    //用于接收消息的队列 公共容器 存放线程往里放 主线程从里边取
    private Queue<string> receiveMgsQueue = new Queue<string>(); 
    public static NetMgr Instance => instance;
    //用于收消息的水桶(容器)
    private byte[] bytes = new byte[1024 * 1024];
    //用于返回字节数组大小
    private int receiveNum;
    //客户端Socket
    public Socket socket;
    private bool IsConnect=false;

    void Awake()
    {
        instance = this;    
    }
    void Update()
    {
        if(receiveMgsQueue .Count >0)
        {
            print(receiveMgsQueue.Dequeue());
        }
    }
    //连接服务器
    public void Connect(string ip,int port)
    {//如果是非链接状态,直接返回
        if (IsConnect )
            return;
        if(socket==null)
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //连接服务端
        IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ip),port);
        try
        {
            socket.Connect(ipPoint);
            IsConnect  = true;
            //使用线程池节约性能
            ThreadPool.QueueUserWorkItem(SendMsg);
            ThreadPool.QueueUserWorkItem(ReceiveMsg);
        }
        catch (SocketException e)
        {
            if (e.ErrorCode == 10061)
                print("服务器拒绝连接");
            else
                print("连接失败" + e.ErrorCode + e.Message);
        }
    
    }
    //发送消息
    public void Send(string info)
    {
        sendMgsQueue.Enqueue(info);
    }
    public void SendMsg(object obj)
    {
        if(sendMgsQueue .Count >0)
        {
            socket.Send(Encoding.UTF8.GetBytes(sendMgsQueue.Dequeue()));
        }
    }
    //不停的接收消息
    public void ReceiveMsg(object obj)
    {
        while (IsConnect)
        {
            if (socket.Available > 0)
            {
                receiveNum = socket.Receive(bytes);
                //解析字符数组成字符串,放入公共容器中
                receiveMgsQueue.Enqueue(Encoding.UTF8.GetString(bytes, 0, receiveNum));
            }
        }
 
    }
    public void Close()
    {
        if(socket !=null)
        {
            IsConnect  = false;
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }
    }
    private void OnDestroy()
    {
        Close();
    }
}

主函数入口

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        if(NetMgr .Instance ==null)
        {
            GameObject obj = new GameObject("Net");
            obj.AddComponent<NetMgr>();
        }
        NetMgr.Instance.Connect("127.0.0.1", 8080);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

客户端向服务器发消息

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Lesson7 : MonoBehaviour
{
    public Button btu;
    public InputField input;
    void Start()
    {
        btu.onClick.AddListener(() =>
      {
          if (input.text != "")
          {
              NetMgr.Instance.Send(input.text);
          }
      }
        );
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
相关推荐
天涯过客TYGK1 小时前
unity A星寻路
unity·游戏引擎
KhalilRuan1 小时前
Unity Demo——3D平台跳跃游戏笔记
笔记·游戏·unity·游戏引擎
IPdodo全球网络服务1 小时前
什么是IP关联?跨境卖家如何有效避免IP关联?
网络·网络协议·tcp/ip
南棱笑笑生2 小时前
20250711荣品RD-RK3588开发板在Android13下的开机自启动的配置步骤
网络
知北游天3 小时前
Linux:多线程---同步&&生产者消费者模型
java·linux·网络
EasyCVR3 小时前
EasyCVR视频汇聚平台国标接入设备TCP主动播放失败排查指南
网络·tcp/ip·音视频
kfepiza3 小时前
`nmcli con add type vlan`中的: `ifname` , `dev` ,`vlan.parent`, `id`,`vlan.id`
linux·网络协议·tcp/ip
kfepiza3 小时前
Linux的NetworkManager的`nmcli connection add` 笔记250712
linux·网络协议·tcp/ip
kfepiza3 小时前
Linux的NetworkManager的`nmcli con add type vlan`中, `iframe` 和 `dev` 的区别 笔记250712
linux·tcp/ip
刘孬孬沉迷学习3 小时前
5G标准学习笔记15 --CSI-RS测量
网络·笔记·学习·5g·信息与通信·信号处理