好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Unity实现简单的多人聊天工具

本文实例为大家分享了Unity实现多人聊天工具的具体代码,供大家参考,具体内容如下

代码1 : 服务端代码

using UnityEngine; using System.Net.Sockets; using System.Net; using System.Threading; public class ChatServer : MonoBehaviour { ? ? ? ?// 设置连接端口 ? ? ? ?const int portNo = 500; ? ? ? ?string m_ServerIP = ""; ? ? ? ?// Use this for initialization ? ? ? ?void Start () ? ? ? ?{ ? ? ? ? ? ? ? m_ServerIP = Network.player.ipAddress;//获取本机服务器的IP ? ? ? ? ? ?print("服务器IP:"+m_ServerIP); ? ? ? ?//开启新的线程来执行TCP的监听 ? ? ? ? ? ? ? myThread.Start (); ? ? ? ? //支持后台运行避免最小化后不运行 ? ? ? ? ? ? ? Application.runInBackground = true; ? ? ? ?} ? ? ? ?private void ListenClientConnect () ? ? ? ?{ ? ? ? ? ? ? ? Debug.Log("正在启动服务器!"); ? ? ? ? // 初始化服务器IP ? ? ? ? ? ?IPAddress localAdd = IPAddress.Parse(m_ServerIP); ? ? ? ? ? ? ? // 创建TCP侦听器 ? ? ? ? ? ? ? TcpListener listener = new TcpListener (localAdd, portNo); ? ? ? ? ? ? ? listener.Start (); ? ? ? ? ? ?Debug.Log("服务器正在运行中......."); ? ? ? ? ? ?//温馨提示:建议使用Windows电脑运行服务器,如果是Mac系统一定要看到打印这句话服务器才启动起来了,否则服务器表示没有启动 ? ? ? ? // 循环接受客户端的连接请求 ? ? ? ? while (true) { ? ? ? ? ? ? //编写各个客户端的类,只要监听到有IP连接服务器,就实例化对应的客户端 ? ? ? ? ? ? ? ? ? ? ?ChatClient user = new ChatClient (listener.AcceptTcpClient()); ? ? ? ? ? ? ? ? ? ? ?// 显示连接客户端的IP与端口【只要有新的客户端连接进来就会打印打控制台谁进来了】 ? ? ? ? ? ? ? ? ? ? ?print (user._clientIP + " 加入服务器\n"); ? ? ? ? ? ? ? } ? ? ? ?} }

代码2 :  客户端与服务端交互

using UnityEngine; using System.Collections; using System.Net.Sockets; using System; using System.Text; //各个客户端自身应该有的逻辑【进入服务器离开服务器等】 public class ChatClient : MonoBehaviour { ? ? ? ? static Hashtable ALLClients = new Hashtable ();// 客户端列表 ? ? private TcpClient _client;// 客户端实体 ? ? ?public string _clientIP;// 客户端IP ? ? private string _clientNick;// 客户端昵称 ? ? private byte[] data;// 消息数据 ? ? private bool ReceiveNick = true;//是否从客户端接受到他的昵称[消息分割标识] ? ? ? ?void Awake () ? ? ? ?{ ? ? ? ? ? ? ? Application.runInBackground = true; ? ? ? ?} ? ? //由服务器创建实例 ? ? ? ?public ChatClient (TcpClient client) ? ? ? ?{ ? ? ? ? //客户端实体对象 ? ? ? ? ? ? ? this._client = client; ? ? ? ? ? ? ? this._clientIP = client.Client.RemoteEndPoint.ToString (); ? ? ? ? ? ? ? // 把当前客户端实例添加到客户列表当中 ? ? ? ? ? ? ? //第一个参数时IP,第二个为对应客户端 ? ? ? ? ? ? ? ALLClients.Add (this._clientIP, this); ? ? ? ? ? ? ? data = new byte[this._client.ReceiveBufferSize]; ? ? ? ? ? ? ? // 从服务端获取消息 ? ? ? ? ? ? ? client.GetStream ().BeginRead (data, 0, System.Convert.ToInt32 (this._client.ReceiveBufferSize), ReceiveMessage, null); ? ? ? ?} ? ? ? ?// 从客戶端获取消息 ? ? ? ? void ReceiveMessage (IAsyncResult ar) ? ? ? ?{ ? ? ? ? ? ? ? int bytesRead; ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ?lock (this._client.GetStream()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ?bytesRead = this._client.GetStream ().EndRead (ar); ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? //没有读到数据说明这个客户端已经掉线 ? ? ? ? ? ? ? ? ? ? ?if (bytesRead < 1) { ? ? ? ? ? ? ? ? ? ? ? ? ? ?ALLClients.Remove (this._clientIP); ? ? ? ? ? ? ? ? ? ? ? ? ? ?//广播 ? ? ? ? ? ? ? ? ? ? ? ? ? ?Broadcast (this._clientNick + " 已经离开服务器");//已经离开服务器 ? ? ? ? ? ? ? ? ? ? ? ? ? ?return; ? ? ? ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ? ? ?string messageReceived = Encoding.UTF8.GetString (data, 0, bytesRead); ? ? ? ? ? ? ? ? //这个开关很关键,读取到了发送进来的数据后,默认是收到了对应客户端的昵称的,将这个客户端第一次发来的信息作为昵称,以后的都是他发消息 ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (ReceiveNick) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? this._clientNick = messageReceived; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Broadcast (this._clientNick + " 已经进入服务器");//已经进入服务器 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ReceiveNick = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Broadcast (this._clientNick + ":" + messageReceived); ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ?lock (this._client.GetStream()) { ? ? ? ? ? ? ? ? //尾递归处理 ? ? ? ? ? ? ? ? ? ? ? ? ? ?this._client.GetStream ().BeginRead (data, 0, System.Convert.ToInt32 (this._client.ReceiveBufferSize), ReceiveMessage, null); ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? } catch (Exception ex) { ? ? ? ? ? ? ? ? ? ? ?ALLClients.Remove (this._clientIP); ? ? ? ? ? ? ? ? ? ? ?Broadcast (this._clientNick + " 已经离开服务器");//已经离开服务器 ? ? ? ? ? ? ? } ? ? ? ?} ? ? ? ?// 向一个客戶端发送消息 ? ? ? ? void sendMessage (string message) ? ? ? ?{ ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ?NetworkStream ns; ? ? ? ? ? ? ? ? ? ? ?lock (this._client.GetStream()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ?ns = this._client.GetStream (); ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ?// 对信息进行编码,写入流,别忘记冲刷赶紧缓冲 ? ? ? ? ? ? ? ? ? ? ?byte[] bytesToSend = Encoding.UTF8.GetBytes (message); ? ? ? ? ? ? ? ? ? ? ?ns.Write (bytesToSend, 0, bytesToSend.Length); ? ? ? ? ? ? ? ? ? ? ?ns.Flush (); ? ? ? ? ? ? ? } catch (Exception ex) { ? ? ? ? ? ? ? ? ? ? ?Debug.Log ("Error:" + ex); ? ? ? ? ? ? ? } ? ? ? ?} ? ? ? ?// 向所有客户端广播消息 ? ? ? ? void Broadcast (string message) ? ? ? ?{ ? ? ? ? ? ? ? Debug.Log (message);//打印消息 ? ? ? ? //向在服务器中连接的所有客户端发送最新消息 ? ? ? ? ? ? ? foreach (DictionaryEntry c in ALLClients) { ? ? ? ? ? ? ? ? ? ? ?((ChatClient)(c.Value)).sendMessage (message + Environment.NewLine); ? ? ? ? ? ? // ? \r是回车,英文是Carriage return ?运输返回 ? ? ? ? ? ?B位置 ? ? ? ? ? ? // ? \n是换行,英文是New line ? ? ? ? ? ? ? ? ? ? ? ? ? ?C位置 ? ? ? ? ? ? // ? Enter = 回车+换行(\r\n) 确认按键 ? ? ? ? ? ? ? ? ? ?D位置 ? ? ? ? ? ? //在 Windows 环境中,C# 语言 Environment.NewLine == "\r\n" ? ? ? ? ? ? // B ? ? ? A ? ? ? ? ? ? // D ? ? ? C ? ? ? ? ? ? // 当前编辑光标位置:A ? ? ? ? ? ? //机械打字机有回车和换行两个键作用分别是: ? ? ? ? ? ? //换行就是把滚筒卷一格,不改变水平位置。 ? ? ? ? ? ? //回车就是把水平位置复位,不卷动滚筒。 ? ? ? ? } ? ? } }

代码3 :  客户端与UI交互

using UnityEngine; using System.Net.Sockets; using System; using System.Text; using UnityEngine.UI; //各个客户端聊天的UI交互 public class ClientHandler : MonoBehaviour { ? ? ? ?const int portNo = 500; ? ? ? ?private TcpClient _client; ? ? ? ?private ?byte[] data; ? ? ? ? string nickName = ""; ? ? ? ? string message = ""; ? ? ? ? string sendMsg = ""; ? ? ? ?[SerializeField]InputField m_NickInput; ? ? ? ?[SerializeField]InputField m_SendMsgInput; ? ? ? ?[SerializeField]Text m_ShowMessageText; ? ? [SerializeField] InputField m_IPInput; ? ? ? ?void Update () ? ? ? ?{ ? ? ? ? ? ? ? nickName = m_NickInput.text; ? ? ? ? ? ? ? m_ShowMessageText.text = message; ? ? ? ? ? ? ? sendMsg = m_SendMsgInput.text; ? ? ? ?} ? ? //连接服务器按钮 ? ? ? ?public void ConBtnOnClik () ? ? ? ?{ ? ? ? ? ? ?if (m_IPInput.text != "" || m_IPInput.text != null) ? ? ? ? ? ?{ ? ? ? ? ? ? //真正的当前客户端 ? ? ? ? ? ? ? ?this._client = new TcpClient(); ? ? ? ? ? ? ? ?//连接服务器的IP和端口 ? ? ? ? ? ? ? ?this._client.Connect(m_IPInput.text, portNo); ? ? ? ? ? ? ? ?//获取缓冲区的位元组数目,即缓存区的大小 ? ? ? ? ? ? ? ?data = new byte[this._client.ReceiveBufferSize];//避免去去死,比如有些同志写成1024 ? ? ? ? ? ? ? ?//点击了连接服务器按钮后就将昵称也发送过去 ? ? ? ? ? ? ? ?SendMyMessage(nickName); ? ? ? ? ? ? //当前客户端开始去读取数据流 ? ? ? ? ? ? ? ?this._client.GetStream() ? ? ? ? ? ? ? ? ? ?.BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null); ? ? ? ? ? ?} ? ? ? ? ? ?else ? ? ? ? ? ?{ ? ? ? ? ? ? ? ?Debug.Log("请输入正确的IP"); ? ? ? ? ? ?} ? ? ? ?} ? ? //发送消息按钮 ? ? ? ?public void SendBtnOnClik () ? ? ? ?{ ? ? ? ? //每次将输入消息发送到服务器,并制空输入框 ? ? ? ? ? ? ? SendMyMessage (sendMsg); ? ? ? ? ? ? ? m_SendMsgInput.text = ""; ? ? ? ?} ? ? ? ?/// <summary> ? ? ? ?/// 向服务器发送数据(发送聊天信息) ? ? ? ?/// </summary> ? ? ? ?/// <param name="message"></param> ? ? ? ? void SendMyMessage (string message) ? ? ? ?{ ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ?NetworkStream ns = this._client.GetStream (); ? ? ? ? ? ? //因为我们现在只做文本信息的传输,所以这里使用UTF编码来写入和识别 ? ? ? ? ? ? ? ? ? ? ?byte[] data = Encoding.UTF8.GetBytes (message); ? ? ? ? ? ? ? ? ? ? ?ns.Write (data, 0, data.Length); ? ? ? ? ? ? ? ? ? ? ?ns.Flush ();//冲刷赶紧buffer缓冲,准备下次再接受新的数据 ? ? ? ? ? ? ? } catch (Exception ex) { ? ? ? ? ? ? ? ? ? ? ?Debug.Log ("Error:" + ex); ? ? ? ? ? ? ? } ? ? ? ?} ? ? ? ?/// <summary> ? ? ? ?/// 接收服务器的数据(聊天信息) ? ? ? ?/// </summary> ? ? ? ?/// <param name="ar"></param> ? ? ? ? void ReceiveMessage (IAsyncResult ar) ? ? ? ?{ ? ? ? ? ? ? ? try { ? ? ? ? ? ? //当上面的读取方法执行完毕后,会自动回调这个方法 ? ? ? ? ? ? ? ? ? ? ?int bytesRead = this._client.GetStream ().EndRead (ar);//读取完毕 ? ? ? ? ? ? ? ? ? ? ?if (bytesRead < 1) { ? ? ? ? ? ? ? ? //说明没有读取到任何信息 ? ? ? ? ? ? ? ? ? ? ? ? ? ?return; ? ? ? ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? //读取到文本信息后使用UTF编码解码 ? ,并连续拼接起来 ? ? ? ? ? ? ? ? ? ? ? ? ? ?message += Encoding.UTF8.GetString (data, 0, bytesRead); ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? //再次去读取信息 ? ? ? ? ? ? _client.GetStream ().BeginRead (data, 0, Convert.ToInt32 (_client.ReceiveBufferSize), ReceiveMessage, null); ? ? ? ? ? ? ? } catch (Exception ex) { ? ? ? ? ? ? ? ? ? ? ?print ("Error:" + ex); ? ? ? ? ? ? ? } ? ? ? ?} }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

查看更多关于Unity实现简单的多人聊天工具的详细内容...

  阅读:39次