C#中Socket与Unity相结合示例代码
程序员文章站
2023-12-17 14:45:58
前言
初步接触了socket,现使其与unity相结合,做成一个简单的客户端之间可以互相发送消息的一个test。下面话不多说了,来一起看看详细的介绍吧。
方法如下:...
前言
初步接触了socket,现使其与unity相结合,做成一个简单的客户端之间可以互相发送消息的一个test。下面话不多说了,来一起看看详细的介绍吧。
方法如下:
首先,是服务端的代码。
创建一个连接池,用于存储客户端的数量。
using system; using system.net; using system.net.sockets; using system.collections; using system.collections.generic; namespace server { /// <summary> /// 对象池 /// </summary> public class conn { //常量,用于表示传输的字节最大数量,最大接收的字节数 public const int buffer_size = 1024; //socket public socket socket; //是否连接 public bool isuse = false; //传输数组,用来存储接受到的数据 public byte[] readbuff = new byte[buffer_size]; public int buffcount = 0; /// <summary> /// 构造函数 /// </summary> public conn() { readbuff = new byte[buffer_size]; } /// <summary> /// 初始化 /// </summary> /// <param name="socket"></param> public void init(socket socket) { this.socket = socket; isuse = true; buffcount = 0; } /// <summary> /// 缓冲区剩下的字节数 /// </summary> /// <returns></returns> public int buffremain() { return buffer_size - buffcount; } /// <summary> /// 获得客户端地址 /// </summary> /// <returns></returns> public string getadress() { if (!isuse) { return "无法获得地址"; } else { return socket.remoteendpoint.tostring(); } } /// <summary> /// 关闭连接 /// </summary> public void close() { if (!isuse) { return; } else { console.writeline("断开连接" + getadress()); socket.close(); isuse = false; } } } }
对象池创建完成后,需要在创建一个连接类,用来维护客户端的连接。
using system; using system.collections.generic; using system.linq; using system.text; using system.net; using system.net.sockets; namespace server { class serv { //监听套接字 public socket listenfd; //客户端链接 public conn[] conns; //最大的连接数量 public int maxconn = 50; //获取链接池索引,返回负数表示获取失败 public int newindex() { if(conns==null) { return -1; } for (int i = 0; i < conns.length;i++ ) { if(conns[i]==null) { conns[i] = new conn(); return i; }else if(conns[i].isuse==false) { return i; } } return -1; } //开启一个服务器 public void start(string host,int port) { conns = new conn[maxconn]; for (int i = 0; i < maxconn;i++ ) { conns[i] = new conn(); } listenfd = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); ipaddress ipadr = ipaddress.parse(host); ipendpoint ipep = new ipendpoint(ipadr, port); //与一个本地终结点相关联 listenfd.bind(ipep); //监听 listenfd.listen(maxconn); listenfd.beginaccept(acceptcb, listenfd); } //acceptcb回调 public void acceptcb(iasyncresult ar) { try { socket ssocket = ar.asyncstate as socket; socket socket = ssocket.endaccept(ar); int index = newindex(); if(index<0) { socket.close(); console.writeline("连接已满"); } else { conn conn = conns[index]; conn.init(socket); string adr = conn.getadress(); console.writeline("客户端连接[" + adr + "conn池id: " + index); conn.socket.beginreceive(conn.readbuff, conn.buffcount, conn.buffremain(), socketflags.none, receivecb, conn); } listenfd.beginaccept(acceptcb, listenfd); }catch(socketexception ex) { console.writeline(ex); } } //receivecb回调 public void receivecb(iasyncresult ar) { conn conn = (conn)ar.asyncstate; try { int count = conn.socket.endreceive(ar); if(count<=0) { console.writeline("收到:" + conn.getadress() + "断开连接"); conn.close(); return; } string str = encoding.utf8.getstring(conn.readbuff,0,count); console.writeline("接收到[" + conn.getadress() + "]数据" + str); byte[] bytes = encoding.utf8.getbytes(str); for (int i = 0; i < conns.length;i++ ) { if(conns[i]==null) continue; if (!conns[i].isuse) continue; console.writeline("将消息传送给" + conns[i].getadress()); conns[i].socket.send(bytes); } conn.socket.beginreceive(conn.readbuff, conn.buffcount, conn.buffremain(), socketflags.none,receivecb, conn); } catch(socketexception ex) { console.writeline(ex); console.writeline("收到:" + conn.getadress() + "断开连接"); conn.close(); } } } }
最后是创建一个unity的工程,搭建一个简单的页面,通过下面的代码你可以了解需要哪些组件
using unityengine; using system.collections; using system.net; using system.net.sockets; using unityengine.ui; using system.collections.generic; using system; public class net : monobehaviour { //ip和端口 public inputfield hostinput; public inputfield portinput; //显示客户端接受的消息 public text recvtext; public string recvstr; //显示客户端ip和端口 public text clienttext; //聊天输入框 public inputfield textinput; socket socket; const int buffer_size = 1024; public byte[] readbuff = new byte[buffer_size]; void fixedupdate() { recvtext.text = recvstr; } //连接服务器(需要一个button触发) public void connetion() { recvtext.text = ""; socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); string host = hostinput.text; int port = int.parse(portinput.text); socket.connect(host, port); clienttext.text = "客户端地址:"+socket.localendpoint.tostring(); socket.beginreceive(readbuff, 0, buffer_size, socketflags.none, receivecb,socket); } /// <summary> /// 接受数据 /// </summary> /// <param name="ar"></param> public void receivecb(iasyncresult ar) { try { int count = socket.endreceive(ar); string str = system.text.encoding.utf8.getstring(readbuff, 0, count); if (recvstr.length > 300) recvstr = ""; recvstr += socket.localendpoint.tostring()+str + "\n"; debug.log("12346"); socket.beginreceive(readbuff, 0, buffer_size, socketflags.none, receivecb, socket); }catch(socketexception ex) { debug.log(ex); } } /// <summary> /// 发送数据,(需要一个button触发) /// </summary> public void send() { string str = textinput.text; byte[] tex = system.text.encoding.utf8.getbytes(str); try { socket.send(tex); } catch(socketexception ex) { debug.log(ex); } } }
以上内容出自罗培羽老师《unity3d网络游戏实战》一书。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。