Unity网络开发记录(三):封装服务端的相关socket

客户端与服务端通讯socket

封装此类,是为了方便维护客户端和服务端建立连接后返回的socket

包含了所需要的基础的socket 以及 该socket所对应的id号,方便进行管理

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace TechTcpServerTest2
{
    internal class ClientTcpSockt
    {
        private static int CLIENT_NUMBER = 0;
        public int clientID = 0;
        private Socket? socket;

        public ClientTcpSockt(Socket _socket)
        {
            socket = _socket;
            clientID = CLIENT_NUMBER;
            ++CLIENT_NUMBER;
        }

        public void Send(string info)
        {
            if (socket != null)
            {
                try
                {
                    socket.Send(Encoding.UTF8.GetBytes(info));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);   
                }
            }
        }

        public void Receive()
        {
            if (socket != null)
            {
                try
                {
                    if (socket.Available > 0)
                    {
                        byte[] buffer = new byte[1024 * 5];
                        int num = socket.Receive(buffer);
                        ThreadPool.QueueUserWorkItem(HandleMsg, Encoding.UTF8.GetString(buffer, 0, num));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }

        private void HandleMsg(object obj)
        {
            string info = (string)obj;
            if (socket != null)
            {
                Console.WriteLine("{0}客户端,信息:{1}", socket.RemoteEndPoint, info);
            }
        }

        public void Close()
        {
            if (socket != null)
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                socket = null;
            }
        }
    }
}

服务端socket

此类具有基础的socket 以及 一个客户端类的字典,按照 特定的id与socket进行对应

对于客户端的连接请求以及消息的接收处理依旧采用多线程去处理

对于accept一直循环去监听,如果有新连接就加入到字典当中

对于receive,就一直循环的调用字典中存储对象的receive方法

关闭对客户端的连接,只需要循环调用字典内 刚刚封装的客户端-服务端socket对象中的关闭方法就行

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace TechTcpServerTest2
{
    internal class ServerTcpSocket
    {
        private Socket socket;
        private Dictionary<int, ClientTcpSockt> clientDic = new Dictionary<int, ClientTcpSockt>();
        private bool isConnected;
        public bool IsConnected => isConnected;

        public void Start(string ip, int port, int num)
        {
            isConnected = false;
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ip), port);
            socket.Bind(ipPoint);
            socket.Listen(num);

            ThreadPool.QueueUserWorkItem(Accept);
            ThreadPool.QueueUserWorkItem(Receive);
        }

        public void Accept(object obj)
        {
            while (!isConnected)
            {
                try
                {
                    Socket client = socket.Accept();
                    ClientTcpSockt clientTcpSockt = new ClientTcpSockt(client);
                    clientDic.Add(clientTcpSockt.clientID, clientTcpSockt);
                    clientTcpSockt.Send("服务器连接成功");
                }
                catch (Exception e)
                {
                    Console.WriteLine("客户端连接出错 " + e.Message);
                }
            }
        }

        public void Receive(object obj)
        {
            while (!isConnected)
            {
                try
                {
                    if (clientDic.Count > 0)
                    {
                        foreach (var item in clientDic.Values)
                        {
                            item.Receive();
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("客户端接收出错 " + e.Message);
                }
            }
        }

        public void Close()
        {
            foreach(var item in clientDic.Values)
            {
                item.Close();
            }
            clientDic.Clear();

            isConnected = true;
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
            socket = null;
        }

        public void Broadcast(string info)
        {
            if (socket != null)
            {
                foreach (var item in clientDic.Values)
                {
                    item.Send(info);
                }
            }
        }
    }
}

启动

开始先初始化一个与服务相关的socket类对象,调用前面所写的start方法初始化绑定ip地址、端口号、监听大小

然后该类对象会自动进行处理相应的客户端连接,以及相关的通讯工作。对于客户端,最基本的代码connect就可以连接该服务器并进行通讯

cs 复制代码
namespace TechTcpServerTest2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ServerTcpSocket socket = new ServerTcpSocket();
            socket.Start("127.0.0.1", 8080, 1024);
            Console.WriteLine("服务器开启");
            while(true)
            {
                string input = Console.ReadLine();
                if (input == "Quit")
                {
                    socket.Close();
                }
                else if (input.Substring(0, 2) == "B:")
                {
                    socket.Broadcast(input.Substring(2));
                }
            }
        }
    }
}

启动客户端和该新的服务端后,可以发现依然能够正常连接

相关推荐
发光小北1 小时前
EtherNet/IP 转 ModbusTCP 网关现场应用中会遇到什么问题?
服务器·网络·tcp/ip
海宇大数据1 小时前
零信任架构实战:基于海宇全能小微企业报告构建自动化持牌网络小贷小微商户极速助业贷秒级全维风险决策网关
网络·人工智能·架构·自动化
Aman19842 小时前
Claude Code做Unity项目移植(一):从零散工具到团队式
unity·游戏开发·vibe coding·claude code·项目迁移
tongyiixiaohuang2 小时前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
一只鹿鹿鹿3 小时前
智算算力、AI-芯片与产品解析(PPT文件)
大数据·运维·网络·人工智能·物联网·1024程序员节
开源必胜3 小时前
Socket、异步非阻塞 I/O 与 NGINX、Netty 模型
网络·tcp/ip·nginx
沫璃染墨3 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
蓝祁子yoky4 小时前
Qt学习日记 Day13:网络编程(一)-TCP基础与Socket实战
网络·qt·学习
地狱为王4 小时前
Unity使用VoxLock实现语音隔离
unity·游戏引擎·音频处理·voxlock
箓维4 小时前
TCP Socket的进阶实现
网络·笔记·tcp/ip