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

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

相关推荐
遇见火星3 分钟前
2025年Linux 安全与运维指南
网络
苏格拉真没有底13 分钟前
python实现mqtt消息转Tcp消息
网络·python·tcp/ip
dxaiofcu17 分钟前
双网卡电脑,IP地址漂移
linux·服务器·网络
君莫愁。39 分钟前
【Unity】搭建基于字典(Dictionary)和泛型列表(List)的音频系统
数据结构·unity·c#·游戏引擎·音频
煲冬瓜的程序猿3 小时前
BGP(三)联盟、反射器
网络·网络协议
Joeysoda3 小时前
JavaEE进阶(2) Spring Web MVC: Session 和 Cookie
java·前端·网络·spring·java-ee
暴躁的小胡!!!3 小时前
Linux权限维持之vim python 扩展后门(五)
linux·运维·服务器·网络·安全
圣圣不爱学习3 小时前
Calico-BGP FullMesh模式与RR模式 Day04
运维·网络
zhgjx-dengkewen3 小时前
华为eNSP:实验 OSPF单区域
运维·网络·华为·智能路由器
风格6544 小时前
DR和BDR的选举规则
网络·智能路由器