Unity实现局域网聊天室功能
程序员文章站
2022-06-23 12:13:49
基于unity实现一个简单的局域网聊天室,供大家参考,具体内容如下学习unity有一点时间了,之前学的都是做客户端的一些内容,现在开始学习联网。我的这个是在观看了 siki 的教学内容来做的,也有自己...
基于unity实现一个简单的局域网聊天室,供大家参考,具体内容如下
学习unity有一点时间了,之前学的都是做客户端的一些内容,现在开始学习联网。我的这个是在观看了 siki 的教学内容来做的,也有自己的一点点小小的改动在里面。纯粹用于练手了。
因为本人也是小白一枚,所以,有错误的地方或者更好的实现方法,也希望有大神能帮忙指正,多谢!
整体过程分为两部分:构建服务端、构建客户端。
服务端:
大概思路:
1. 声明socket连接以及绑定ip和端口,这里面使用
using system; using system.collections.generic; using system.linq; using system.text; using system.threading.tasks; using system.net.sockets; using system.net; namespace serverapplication { class program { public static string ip; public static int port; static list<client> clientlist = new list<client>(); static socket serversocket; static void main(string[] args) { //绑定ip和端口 bindipandport(); // while (true) { socket clientsocket = serversocket.accept(); client client = new client(clientsocket); clientlist.add(client); console.writeline("一台主机进入连接"); } } /// <summary> /// 广播数据 /// </summary> public static void broadcostmsg(string s) { list<client> notconnectedlist = new list<client>(); foreach (var item in clientlist) { if(item.isconnected) { item.sendmsg(s); } else { notconnectedlist.add(item); } } foreach (var item in notconnectedlist) { clientlist.remove(item); } } /// <summary> /// 绑定ip和端口 /// </summary> public static void bindipandport() { //创建一个serversocket serversocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); //声明ip和端口 console.writeline("输入ip地址:"); ip = console.readline(); string ipstr = ip; console.writeline("请输入端口:"); port = int.parse(console.readline()); int port = port; ipaddress serverip = ipaddress.parse(ipstr); endpoint serverpoint = new ipendpoint(serverip, port); //socket和ip进行绑定 serversocket.bind(serverpoint); //监听最大数为100 serversocket.listen(100); } } }
using system; using system.collections.generic; using system.linq; using system.text; using system.threading.tasks; using system.net.sockets; using system.threading; namespace serverapplication { class client { public socket clientsocket; //声明一个线程用于接收信息 thread t; //接收信息所用容器 byte[] data = new byte[1024]; //构造函数 public client(socket s) { clientsocket = s; t = new thread(receivemsg); t.start(); } /// <summary> /// 接收数据 /// </summary> void receivemsg() { while(true) { if (clientsocket.poll(10,selectmode.selectread)) { break; } data = new byte[1024]; int length = clientsocket.receive(data); string message = encoding.utf8.getstring(data, 0, length); program.broadcostmsg(message); console.writeline("收到消息:" + message); } } /// <summary> /// 发送数据 /// </summary> /// <param name="s"></param> public void sendmsg(string message) { byte[] data = encoding.utf8.getbytes(message); clientsocket.send(data); } //判断此client对象是否在连接状态 public bool isconnected { get { return clientsocket.connected; } } } }
客户端:
a.ui界面
ui界面是使用ugui实现的
登录用户可以自己取名进行登录(发言时用于显示),使用时需要输入服务端的ip地址和端口号
下面是聊天室的页面,在输入框内输入要发送的消息,点击send,将信息发送出去
这是服务端的信息
b.关于客户端的脚本
(1)这是clientmanager,负责与服务端进行连接,通信
using system.collections; using system.collections.generic; using unityengine; using system.net.sockets; using system.net; using system.text; using unityengine.ui; using system.threading; public class clientmanager : monobehaviour { //ip:192.168.1.7 public string ipaddressstr; public int port; public text iptexttoshow; //socket private socket clientserver; //文本输入框 public inputfield inputtxt; public string inputmsgstr; //接收 thread t; public text receivetextcom; public string message; // use this for initialization void start() { iptexttoshow.text = ipaddressstr; // connectedtoserver(); } // update is called once per frame void update() { if (message != null && message != "") { receivetextcom.text = receivetextcom.text + "\n" + message; message = ""; } } /// <summary> /// 连接服务器 /// </summary> public void connectedtoserver() { clientserver = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); //声明ip地址和端口 ipaddress serveraddress = ipaddress.parse(ipaddressstr); endpoint serverpoint = new ipendpoint(serveraddress, port); ipaddressstr = ipinfo.ipstr; port = ipinfo.portstr; //开始连接 clientserver.connect(serverpoint); t = new thread(receivemsg); t.start(); } /// <summary> /// 接收消息 /// </summary> /// <returns>“string”</returns> void receivemsg() { while (true) { if (clientserver.connected == false) { break; } byte[] data = new byte[1024]; int length = clientserver.receive(data); message = encoding.utf8.getstring(data, 0, length); //debug.log("有消息进来"); } } /// <summary> /// 发送string类型数据 /// </summary> /// <param name="input"></param> public void sendmsg() { debug.log("button clicked"); //message = "我:" + inputtxt.text; inputmsgstr = inputtxt.text; byte[] data = encoding.utf8.getbytes(ipinfo.name+":"+inputmsgstr); clientserver.send(data); } private void ondestroy() { clientserver.shutdown(socketshutdown.both); clientserver.close(); } private void onapplicationquit() { ondestroy(); } }
(2)scenemanager,用于场景切换,这里只是利用gameobject进行setactive()来实现,并不是创建了单独的scene进行管理。
using system.collections; using system.collections.generic; using unityengine; public class scenemanager : monobehaviour { public gameobject loginpanel; public gameobject communicatingpanel; // use this for initialization public void onswitch() { loginpanel.setactive(false); communicatingpanel.setactive(true); } }
(3)loginpanel和ipinfo,一个挂载在登录界面上,一个是数据模型,用于存储数据。
using system.collections; using system.collections.generic; using unityengine; using unityengine.ui; public class loginpanel : monobehaviour { public text nameinputtxt; public text ipinputtxt; public text portinputtxt; //private string name; //private string ipstr; //private string portstr; public void onloginclick() { ipinfo.name = nameinputtxt.text; ipinfo.ipstr = ipinputtxt.text; ipinfo.portstr = int.parse(portinputtxt.text); } }
public static class ipinfo { public static string name; public static string ipstr; public static int portstr; }
总结:第一次写学习博,还有很多地方要学习啊。
留待解决的问题:此聊天室只能用于局域网以内,广域网就无法实现通信了,还要看看怎么实现远程的一个通信,不然这个就没有存在的意义了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。