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

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()
    {
        
    }
}
相关推荐
开开心心就好2 分钟前
系统管理工具,多功能隐私清理文件粉碎工具
java·网络·windows·r语言·电脑·excel·symfony
逑之23 分钟前
C语言笔记15:动态内存管理
c语言·网络·笔记
hui函数30 分钟前
如何解决 pip install 网络报错 403 Forbidden(访问被阻止)问题
网络·pip
乾元37 分钟前
现场运维机器人的工程化落地——移动探针采集 + AI 诊断,在真实网络中的实现路径
运维·网络·人工智能·架构·机器人·自动化
鲨莎分不晴41 分钟前
Docker 网络深度解析:打破容器的“孤岛效应”
网络·docker·容器
liulilittle1 小时前
rinetd 端口转发工具技术原理
linux·服务器·网络·c++·端口·通信·转发
Filotimo_1 小时前
桥接服务概念
网络协议·网络安全·信息与通信
镜中人★1 小时前
408计算机网络考纲知识点(更新中)
网络·网络协议·计算机网络
xflySnail1 小时前
nas服务域名高速访问-获取公网IP和端口
网络·tcp/ip·智能路由器
fy zs1 小时前
应用层自定义协议和序列化
linux·网络·c++