目录
🟥 认识Socket
🟧 创建一个Socket服务器
1️⃣ 服务器端
2️⃣ Unity端(客户端)
🟨 创建异步Socket Conn类
🟩 创建异步Socket Sever类
1️⃣ 第一步:添加Server类
2️⃣ 第二步:改Main方法
3️⃣ 第三步:调试
🟦 实战:开发一款多人聊天室
🟥 认识Socket
Skcket:套接字
Socket怎样传输数据?
客户端:
1、链接:connect,连接到服务器Accept
2、写入:write——服务器read 往服务器发送请求/向服务器写入账号密码等
3、读取:read——服务器write 客户端读取服务器发来的请求,根据发来的信息进行下一步操作
4、关闭:close——服务器close 如果一直连接socket,会占用资源
服务端:
1、绑定:Bind
2、监听:Listen
ps:1,2步是先把服务器开启起来进行监听,这样客户端才能访问进来
3、创建一个新的链接:Accept。因为服务器不可能只和一个客户端连接,所以和当前客户端建立一个新的连接,当再来别的客户端连接时,再创建新的链接
4、读取:Read 当收到客户端write请求时,读取数据库是否有该账号密码等,进行数据的验证
5、写入:write 当服务器在数据库读取到数据时,服务器返回/发送请求(查询到信息)给客户端
6、关闭:close
🟧 创建一个Socket服务器
注:本段是同步
同步和异步的区别:
同步:只能监听一个
异步:可监听多个(真正根据listdfd.Listen(0); //监听的个数 0代表不限制,同步模式即使这样写也只监听一个)
1️⃣ 服务器端
vs安装:.NET桌面开发
VS新建:控制台应用(.NET Framework) 文件名:mysocket
代码如下:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;namespace mysocket
{class Program{static void Main(string[] args){Socket listdfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAdr = IPAddress.Parse("127.0.0.1"); //服务器地址IPEndPoint ipEp = new IPEndPoint(ipAdr, 1234); //服务器地址+端口号(端口号可随意)listdfd.Bind(ipEp);listdfd.Listen(0); //监听的个数 0代表不限制Console.WriteLine("服务器启动成功");while (true){Socket connfd = listdfd.Accept(); //创建一个新的链接Console.WriteLine("服务器Accept成功");byte[] readbuff = new byte[1024];int count = connfd.Receive(readbuff); //接受客户端信息:有数据发送过来就会接收string str = Encoding.Default.GetString(readbuff, 0, count);Byte[] bytes = Encoding.Default.GetBytes("服务器输出" + str);connfd.Send(bytes);}}}
}
2️⃣ Unity端(客户端)
build Settings——Resolution and Presentation——Run in background(勾选),允许你的游戏在后台运行。若取消勾选,则切换到后台时,你的游戏将失去响应
创建connect脚本挂载到Camera,代码如下
using UnityEngine;
using System.Net.Sockets;public class connect : MonoBehaviour {Socket socket;const int buff_size = 1024;byte[] readbuff = new byte[buff_size];private void Start(){connection();}public void connection(){socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);string host = "127.0.0.1";int port = 1234;socket.Connect(host, port);print("客户端地址" + socket.LocalEndPoint); //显示客户端连接信息string str = "nihao";byte[] bytes = System.Text.Encoding.Default.GetBytes(str);socket.Send(bytes);int count = socket.Receive(readbuff);str = System.Text.Encoding.Default.GetString(readbuff, 0, count);print(str);socket.Close();}
}
此时,调试VS,启动Unity,观察到以下结果
🟨 创建异步Socket Conn类
在二基础上,打开服务端,添加Conn类,代码如下
using System;
using System.Net.Sockets;namespace mysocket
{/// /// 处理客户端链接的类/// class Conn{//定义缓冲区public const int buff_size = 1024;//定义服务器public Socket socket;//是否使用public bool isUse = false;public byte[] readBuff = new byte[buff_size];public int buffCount = 0;public Conn(){readBuff = new byte[buff_size];}//初始化public void Init(Socket socket){this.socket = socket;isUse = true;buffCount = 0;}//缓冲所剩余的字节数public int BuffRemain(){return buff_size - buffCount;}//获取客户端地址public string GetAdress(){if (!isUse)return "无法获取地址";return socket.RemoteEndPoint.ToString();}//关闭连接public void Close(){if (!isUse)return;Console.WriteLine(GetAdress() + "与服务器断开连接");socket.Close();isUse = false;}}
}
🟩 创建异步Socket Sever类
1️⃣ 第一步:添加Server类
在第三基础上,同样在服务器端添加Server类,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;namespace mysocket
{class Server{//监听嵌套字public Socket listedfd;//客户端连接public Conn[] conns;//最大连接数public int maxConn = 50;//获取连接池,返回负数表示连接失败public int NewIndex(){if (conns == null)return -1; //代表没有连接成功for(int i = 0; i }
2️⃣ 第二步:改Main方法
将Program的Main()内方法删掉,改为如下异步方法(原内容为同步)
using System;namespace mysocket
{class Program{static void Main(string[] args){Server server = new Server();server.Start("127.0.0.1", 1234);while (true){string str = Console.ReadLine();switch (str){case "quit": //关闭socketreturn;}}}}
}
3️⃣ 第三步:调试
在Main界面调试,若出现“服务器启动成功”,则代表成功
🟦 实战:开发一款多人聊天室
基于以上内容,打开Unity的客户端,将connect脚本内容改为如下所示:
using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;
using System;public class connect : MonoBehaviour {//服务器地址、服务器端口、聊天输入框public InputField hostInput, portInput,TextInput;//客户端收到的信息public Text connecttext;public Text txtstr; //用于UI显示服务器发送过来的数据public string serverstr; //注:必须为public!服务器发送回来的数据//SocketSocket socket;const int buff_size = 1024;public byte[] readbuff = new byte[buff_size];private void Update(){txtstr.text = serverstr;}//连接服务器,绑定“连接”按钮public void Connection(){txtstr.text = "";socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//开始连接服务器string host = hostInput.text;int port = int.Parse(portInput.text); //转化为intsocket.Connect(host, port);print("客户端地址" + socket.LocalEndPoint); //输出:客户端地址127.0.0.1:54000connecttext.text = socket.LocalEndPoint.ToString();//开始接收数据//public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socket_flags, AsyncCallback callback, object state);socket.BeginReceive(readbuff, 0, buff_size, SocketFlags.None, ReceiveCb, null);}//回调方法void ReceiveCb(IAsyncResult ar){try{//接收数据的大小int count = socket.EndReceive(ar);string str = System.Text.Encoding.Default.GetString(readbuff, 0, count);if (serverstr.Length > 300) serverstr = "";serverstr += str + "\n"; //服务器发送回来的数据(经过加换行处理,且公用放在外面)+=接收数据+ "\n"//继续接收数据socket.BeginReceive(readbuff, 0, buff_size, SocketFlags.None, ReceiveCb, null);}catch(Exception ex){txtstr.text = "连接已经断开" + ex.Message;socket.Close();}}public void Send(){string str = TextInput.text;byte[] bytes = System.Text.Encoding.Default.GetBytes(str);try{socket.Send(bytes);}catch{}}
}
Unity界面如下
现在运行Unity,输入127.0.0.1,端口1234,即可开始通讯
unity发布exe,运行多个exe,可在多个客户端之间进行实时通讯
大家还有什么问题,欢迎在下方留言!
如果你有 技术的问题 或 项目开发
都可以加下方联系方式
和我聊一聊你的故事🧡