【Unity网络通讯】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、了解编写服务器demo

一、基础知识
请添加图片描述
Server:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace Server1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //Socket:套接字 :一个集合,IP地址和端口号、双方都需要同时满足的协议,地址族
            //AddressFamily:地址族
            // SocketType:传输类型,如果使用TCP协议的话,就选用Stream流式传输,如果使用UDP协议,就选择Dgram
            // ProtocolType:协议类型
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;//端口号,1-65535 ,一般1-1024系统端口,BSD保留端口 1024-5000临时端口,剩余的为用户自定义的端口

            //重点掌握:使用服务器进行数据传输
            serverSocket.Bind(new IPEndPoint(IP,port));
            serverSocket.Listen(10);//参数表示同一时间内能处理的最大消息数
            Console.WriteLine("服务器启动了");
            
            //接受,接受一个客户端的连接
            Socket clientSocket = serverSocket.Accept(); //阻塞函数
            Console.WriteLine("服务器接受了一个客户端的连接,客户端的详细数据为:"+clientSocket.RemoteEndPoint.ToString());
            byte[] msgArr = new byte[1024];
            clientSocket.Receive(msgArr);
            string msg = Encoding.UTF8.GetString(msgArr);
            Console.WriteLine("从客户端接受到的数据为:"+msg);


            Console.ReadKey();
        }
    }
}

Client:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace Client1_0
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //客户端不需要绑定自己的IP地址和端口号
            //而是去连接服务器的IP地址和端口号
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;
            //Connect 连接,连接到一个终端()
            clientSocket.Connect(new IPEndPoint(IP, port));
            Console.WriteLine("连接到了服务器");

            string connect = "666666"; //简体中文的编码格式:UTF-8,GB2312

            byte[] msg = Encoding.UTF8.GetBytes(connect);
            clientSocket.Send(msg);

            Console.ReadLine();
        }
    }
}

二、一之中的不足:只能接受一个客户端发送的消息,如何改进?

利用多线程:
改进之后的server代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Server1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //Socket:套接字 :一个集合,IP地址和端口号、双方都需要同时满足的协议,地址族
            //AddressFamily:地址族
            // SocketType:传输类型,如果使用TCP协议的话,就选用Stream流式传输,如果使用UDP协议,就选择Dgram
            // ProtocolType:协议类型
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;//端口号,1-65535 ,一般1-1024系统端口,BSD保留端口 1024-5000临时端口,剩余的为用户自定义的端口

            //重点掌握:使用服务器进行数据传输
            serverSocket.Bind(new IPEndPoint(IP,port));
            serverSocket.Listen(10);//参数表示同一时间内能处理的最大消息数
            Console.WriteLine("服务器启动了");

            Thread thread = new Thread(AcceptClient);
            thread.Start(serverSocket);

            Console.ReadKey();
        }

        //接受客户端发送的连接请求
        private static void AcceptClient(object obj)
        {
            Socket serverSocket = obj as Socket;//父类转为子类
            if(serverSocket == null)
            {
                return;
            }
            //Accept接受,接受一个客户端的连接
            Socket clientSocket = serverSocket.Accept(); //阻塞函数
            Console.WriteLine("服务器接受了一个客户端的连接,客户端的详细数据为:" + clientSocket.RemoteEndPoint.ToString());

            //开启接受客户端发送消息的线程
            Thread thread = new Thread(ReceiveMessage);
            thread.Start(clientSocket);
            //递归调用
            AcceptClient(serverSocket);
        }

        //接受客户端发送的消息
        private static void ReceiveMessage(object obj)
        {
            Socket clientSocket = obj as Socket;
            if(clientSocket == null)
            {
                return;
            }
            byte[] msgArr = new byte[1024];
            clientSocket.Receive(msgArr);
            string msg = Encoding.UTF8.GetString(msgArr);
            Console.WriteLine("从客户端接受到的数据为:" + msg);

            ReceiveMessage(clientSocket);
        }
    }
}

1.消息的广播

server:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Server1._0
{
    class Program
    {
        //用来存放连接进来的客户端
        static List<Socket> clientList = new List<Socket>();

        static void Main(string[] args)
        {
            //Socket:套接字 :一个集合,IP地址和端口号、双方都需要同时满足的协议,地址族
            //AddressFamily:地址族
            // SocketType:传输类型,如果使用TCP协议的话,就选用Stream流式传输,如果使用UDP协议,就选择Dgram
            // ProtocolType:协议类型
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;//端口号,1-65535 ,一般1-1024系统端口,BSD保留端口 1024-5000临时端口,剩余的为用户自定义的端口

            //重点掌握:使用服务器进行数据传输
            serverSocket.Bind(new IPEndPoint(IP,port));
            serverSocket.Listen(10);//参数表示同一时间内能处理的最大消息数
            Console.WriteLine("服务器启动了");

            Thread thread = new Thread(AcceptClient);
            thread.Start(serverSocket);

            Console.ReadKey();
        }

        //接受客户端发送的连接请求
        private static void AcceptClient(object obj)
        {
            Socket serverSocket = obj as Socket;//父类转为子类
            if(serverSocket == null)
            {
                return;
            }
            
            //Accept接受,接受一个客户端的连接
            Socket clientSocket = serverSocket.Accept(); //阻塞函数
            Console.WriteLine("服务器接受了一个客户端的连接,客户端的详细数据为:" + clientSocket.RemoteEndPoint.ToString());
            clientList.Add(clientSocket);//加入List容器

            //开启接受客户端发送消息的线程
            Thread thread = new Thread(ReceiveMessage);
            thread.Start(clientSocket);
         
            //递归调用
            AcceptClient(serverSocket);
        }

        //接受客户端发送的消息
        private static void ReceiveMessage(object obj)
        {
            Socket clientSocket = obj as Socket;
            if(clientSocket == null)
            {
                return;
            }
            byte[] msgArr = new byte[1024];

            try
            {
                //Receive的返回值类型为int,返回的是这个数据的长度
                int length = clientSocket.Receive(msgArr);
                if(length == 0)
                {
                    clientSocket.Close();
                    return;
                }
                string msg = Encoding.UTF8.GetString(msgArr, 0, length);
                Console.WriteLine("从客户端接受到的数据为:" + msg);
                byte[] messge = new byte[length];
                Array.Copy(msgArr, 0, messge, 0, length);
                for (int i = 0; i < clientList.Count; i++)
                {
                    if(clientList[i] == clientSocket)
                    {
                        continue;
                    }
                    clientList[i].Send(messge);
                }
            }
            catch (Exception e)
            {
                clientSocket.Close();
                return;
            }
            ReceiveMessage(clientSocket);
        }
    }
}

client:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Client1_0
{
    class Program
    {
        static Socket clientSocket;
        static string name="我是朱思焱";
        static void Main(string[] args)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //客户端不需要绑定自己的IP地址和端口号
            //而是去连接服务器的IP地址和端口号
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;
            //Connect 连接,连接到一个终端()
            clientSocket.Connect(new IPEndPoint(IP, port));
            Console.WriteLine("连接到了服务器");

            Thread thread = new Thread(ReceiveMessage);
            thread.Start();

            while (true)
            {
                string connect = name+":"+Console.ReadLine(); //简体中文的编码格式:UTF-8,GB2312

                byte[] msg = Encoding.UTF8.GetBytes(connect);
                clientSocket.Send(msg);
            }
           
        }

        //消息的广播
        /// <summary>
        /// 客户端接受服务器发送的信息
        /// </summary>
        private static void ReceiveMessage()
        {
            //需要一个接受数据的数组
            byte[] msgArr = new byte[1024];

            //使用循环一直接受消息
            while (true)
            {
                //需要知道信息的长度
                int length = clientSocket.Receive(msgArr);
                //解析消息
                string msg = Encoding.UTF8.GetString(msgArr, 0, length);
                //打印
                Console.WriteLine("从服务器接收到的消息为:"+msg);
                
            }

        }
    }
}

2.异步服务器

异步:Async,本质上仍然是一个多线程,异步连接必须
同步:程序由上而下的执行

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace AsyncChatSocket
{
    class Program
    {
        //用于存放连接的客户端
        static List<Socket> clientList = new List<Socket>();
        static void Main(string[] args)
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;//端口号,1-65535 ,一般1-1024系统端口,BSD保留端口 1024-5000临时端口,剩余的为用户自定义的端口
            serverSocket.Bind(new IPEndPoint(IP, port));//重点掌握:使用服务器进行数据传输
            serverSocket.Listen(10);//参数表示同一时间内能处理的最大消息数
            Console.WriteLine("服务器启动了");

            //异步的写法和开启新线程不一样
            serverSocket.BeginAccept(AsyncAccept, serverSocket);

            Console.ReadLine();
        }

       static byte[] msgArr = new byte[1024];
        private static void AsyncAccept(IAsyncResult ar)
        {
            Socket serverSocket = ar.AsyncState as Socket;
            if(serverSocket == null)
            {
                return;
            }
            //获取连接客户端
            Socket clientSocket = serverSocket.EndAccept(ar);
            clientList.Add(clientSocket);

            Console.WriteLine(clientSocket.RemoteEndPoint.ToString());

            //开启异步监听接受数据的方法
            clientSocket.BeginReceive(msgArr, 0, msgArr.Length, SocketFlags.None, AsyncReceive,clientSocket);

            serverSocket.BeginAccept(AsyncAccept, serverSocket);
        }

        private static void AsyncReceive(IAsyncResult ar)
        {
            Socket clientSocket = ar.AsyncState as Socket;
            if (clientSocket == null)
            {
                return;
            }

            try
            {
                //Receive的返回值类型为int,返回的是这个数据的长度
                int length = clientSocket.Receive(msgArr); //也是阻塞函数
                if (length == 0)
                {
                    clientSocket.Close();
                    clientList.Remove(clientSocket);
                    return;
                }
                string msg = Encoding.UTF8.GetString(msgArr, 0, length);
                Console.WriteLine("从客户端接受到的数据为:" + msg);

                byte[] messge = new byte[length];
                Array.Copy(msgArr, 0, messge, 0, length);
                for (int i = 0; i < clientList.Count; i++)
                {
                    if (clientList[i] == clientSocket)
                    {
                        continue;
                    }
                    clientList[i].Send(messge);
                }
            }
            catch (Exception e)
            {
                clientList.Remove(clientSocket);
                return;
            }
            clientSocket.BeginReceive(msgArr, 0, msgArr.Length, SocketFlags.None, AsyncReceive, clientSocket);
        }
    }
}

3.使用面向对象思想改进异步服务器

请添加图片描述
客服代码:

using System.Text;
using System.Threading.Tasks;

namespace AsyncChatSocket
{
    class ClientPeer
    {
        Socket ClientSocket = null;
        byte[] msgArr = new byte[1024];
        public ClientPeer(Socket clientSocket)
        {
            //初始化
            this.ClientSocket = clientSocket;
            clientSocket.BeginReceive(msgArr,0,msgArr.Length,SocketFlags.None,AsyncReceive,null);
        }

        
        //仅仅只做客户端消息的接受
        private void AsyncReceive(IAsyncResult ar)
        {
            try
            {
                int length = ClientSocket.EndReceive(ar);
                if(length == 0)
                {
                    ClientSocket.Close();
                    return;
                }
                string msg = Encoding.UTF8.GetString(msgArr, 0, length);
                Console.WriteLine(msg);
                NetManager.Instance.BoardCastMessage(msg);

            }
            catch (Exception e)
            {
                ClientSocket.Close();
                return;
            }
            ClientSocket.BeginReceive(msgArr, 0, msgArr.Length, SocketFlags.None, AsyncReceive, null);
        }

        //给自己管理的客户端发送消息
        public void SendMessage(byte[] message)
        {
            ClientSocket.Send(message);
        }
        public void SendMessage(string message)
        {
            ClientSocket.Send(Encoding.UTF8.GetBytes(message));
        }
    }
}

客服管理者:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AsyncChatSocket
{
    class NetManager
    {
        private static NetManager _instance = null;
        private NetManager() { }
        public static NetManager Instance
        {
            get
            {
                if(_instance == null)
                {
                    _instance = new NetManager();
                }
                return _instance;
            }
        }

        List<ClientPeer> clientList = new List<ClientPeer>();
        public void AddClient(ClientPeer client)
        {
            clientList.Add(client);
        }

        public void RemoveClient(ClientPeer client)
        {
            clientList.Remove(client);
        }

        //广播消息
        public void BoardCastMessage(string message,ClientPeer client=null)
        {
            for (int i = 0; i < clientList.Count; i++)
            {
                if (clientList[i] == client)
                {
                    continue;
                }
                //通知客服给客户端发送消息
                clientList[i].SendMessage(message);
            }
        }
        public void BoardCastMessage(byte[] message, ClientPeer client = null)
        {
            for (int i = 0; i < clientList.Count; i++)
            {
                if (clientList[i] == client)
                {
                    continue;
                }
                //通知客服给客户端发送消息
                clientList[i].SendMessage(message);
            }
        }

        //单独发送消息
        public void SendMessage(byte[] message,ClientPeer client)
        {
            client.SendMessage(message);
        }
        public void SendMessage(string message, ClientPeer client)
        {
            client.SendMessage(message);
        }
    }
}

服务器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace AsyncChatSocket
{
    class Program
    {
        //用于存放连接的客户端
        //static List<Socket> clientList = new List<Socket>();
        static void Main(string[] args)
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress IP = IPAddress.Parse("192.168.1.96");
            int port = 8888;//端口号,1-65535 ,一般1-1024系统端口,BSD保留端口 1024-5000临时端口,剩余的为用户自定义的端口
            serverSocket.Bind(new IPEndPoint(IP, port));//重点掌握:使用服务器进行数据传输
            serverSocket.Listen(10);//参数表示同一时间内能处理的最大消息数
            Console.WriteLine("服务器启动了");

            //异步的写法和开启新线程不一样
            serverSocket.BeginAccept(AsyncAccept, serverSocket);

            Console.ReadLine();
        }

       static byte[] msgArr = new byte[1024];
        private static void AsyncAccept(IAsyncResult ar)
        {
            Socket serverSocket = ar.AsyncState as Socket;
            if(serverSocket == null)
            {
                return;
            }
            //获取连接客户端
            Socket clientSocket = serverSocket.EndAccept(ar);
            //clientList.Add(clientSocket);
            ClientPeer client = new ClientPeer(clientSocket);

            NetManager.Instance.AddClient(client);

            Console.WriteLine(clientSocket.RemoteEndPoint.ToString());

            //开启异步监听接受数据的方法
            //clientSocket.BeginReceive(msgArr, 0, msgArr.Length, SocketFlags.None, AsyncReceive,clientSocket);

            serverSocket.BeginAccept(AsyncAccept, serverSocket);
        }

        //private static void AsyncReceive(IAsyncResult ar)
        //{
        //    Socket clientSocket = ar.AsyncState as Socket;
        //    if (clientSocket == null)
        //    {
        //        return;
        //    }

        //    try
        //    {
        //        //Receive的返回值类型为int,返回的是这个数据的长度
        //        int length = clientSocket.Receive(msgArr); //也是阻塞函数
        //        if (length == 0)
        //        {
        //            clientSocket.Close();
        //            clientList.Remove(clientSocket);
        //            return;
        //        }
        //        string msg = Encoding.UTF8.GetString(msgArr, 0, length);
        //        Console.WriteLine("从客户端接受到的数据为:" + msg);

        //        byte[] messge = new byte[length];
        //        Array.Copy(msgArr, 0, messge, 0, length);
        //        for (int i = 0; i < clientList.Count; i++)
        //        {
        //            if (clientList[i] == clientSocket)
        //            {
        //                continue;
        //            }
        //            clientList[i].Send(messge);
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        clientList.Remove(clientSocket);
        //        return;
        //    }
        //    clientSocket.BeginReceive(msgArr, 0, msgArr.Length, SocketFlags.None, AsyncReceive, clientSocket);
        //}
    }
}

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值