<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
因為這段時間在學習Socket,所以就試著寫了一個簡單的聊天室。主要分為伺服器端和多個使用者端。利用伺服器端作資料中轉站,實現訊息群發。
using System.Collections.Generic; using System.Net; using System.Net.Sockets; namespace 聊天室_Socket_TCP_伺服器端 { class Program { static List<Client> clients = new List<Client>(); static List<Client> notClients = new List<Client>(); /// <summary> /// 廣播訊息 /// </summary> /// <param name="message"></param> public static void CastMessageTOAllConnetedClients(string message) { foreach (var client in clients) { if (client.Conneted) { client.CastMessage(message); } else { notClients.Add(client); } } foreach (var temp in notClients) { clients.Remove(temp); } } static void Main(string[] args) { Socket tcpSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); tcpSever.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.2"), 8899)); tcpSever.Listen(100);//監聽是否有使用者端發起連線 Console.WriteLine("Begin to listen..."); while (true) { Socket clientSocket = tcpSever.Accept(); if (clientSocket!=null) { Console.WriteLine("A client has connneted..."); Client client = new Client(clientSocket);//將每個新建立的連線通訊放於client類做通訊 clients.Add(client); } } Console.ReadKey(); } } }
using System; using System.Net.Sockets; using System.Text; using System.Threading; namespace 聊天室_Socket_TCP_伺服器端 { /// <summary> /// 利用該類和使用者端做通訊 /// </summary> class Client { public Socket clientSocket; private Thread mesManageTherad; private byte[] bufffer=new byte[20]; public Client(Socket soc) { clientSocket = soc; //由於訊息是不斷傳送的,需要多次進行處理。這裡開一個執行緒,專門用來處理訊息。 mesManageTherad = new Thread(MessageSendFromClient); mesManageTherad.Start(); } private void MessageSendFromClient() { //開啟的執行緒一直檢測使用者端使用者端發過來的訊息 while (true) { //判斷連線是否斷開, SelectMode.SelectRead讀狀態模式。 //poll已斷開返回true if (clientSocket.Poll(10,SelectMode.SelectRead)==true) { clientSocket.Close(); break;//終止本執行緒 } int byteNum = clientSocket.Receive(bufffer);//從使用者端接受訊息 string mes = Encoding.UTF8.GetString(bufffer, 0 , byteNum); Console.WriteLine("使用者端傳送過來的訊息:"+mes); //廣播訊息出去給每個使用者端 Program.CastMessageTOAllConnetedClients(mes);//對CastMessage的一層封裝 } } /// <summary> /// Send messages to Clients /// </summary> public void CastMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data); } /// <summary> /// 判斷是否斷開連線 /// </summary> public bool Conneted { get { return clientSocket.Connected; } } } }
伺服器端邏輯:
這裡的伺服器主要負責建立連線,接受使用者端訊息,廣播使用者端發來的訊息。
伺服器通過socket物件繫結伺服器IP和相應埠號(埠號自己開,沒有被其他軟體佔用就好),通過Listen監聽和伺服器socket物件的Accept方法捕捉連線到伺服器的使用者端socket,將捕捉到的使用者端socket放入List集合中方便統一管理和後面的訊息群發。
關於捕捉到的使用者端socket的邏輯處理放在了Client類中統一管理。
Client類將收到使用者端的訊息進行接受,在Client中開啟一個執行緒用於不斷得檢測是否有新訊息從使用者端傳送過來,若有訊息傳送過來則通過CastMessageTOAllConnetedClients方法(對socket物件的Send方法的封裝)傳送給每一個使用者端。
使用者端是在Unity中使用NGUI外掛簡單開發的一個聊天介面。把指令碼掛在NGUI控制元件上即可。使用者端主要負責顯示訊息,傳送訊息,接收訊息。
using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; public class ChatManager : MonoBehaviour { private string _ipAdress = "192.168.1.2"; private int _port=8899; EndPoint remotPoint; Socket clientSocket; public UIInput buttonInput; private bool isCanSend=false; private string buttonMessage=null; Thread receiveThread; byte[] bufferReceive = new byte[1024]; public UILabel chatWindowLable; private string message = "";//預設為空串 // Use this for initialization void Start () { ConnetToSever(_ipAdress, _port);//與伺服器建立連線 } // Update is called once per frame void Update () { if (message!=null&&message!="") { chatWindowLable.text += "n" + message; message = "";//清空訊息 } } void ConnetToSever(string ipadress,int port) { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); remotPoint = new IPEndPoint(IPAddress.Parse(ipadress),port); //建立連線 clientSocket.Connect(remotPoint); //因為是一直在準備接受的狀態,所以開啟一個執行緒來負責處理接受訊息 receiveThread = new Thread(ReceiveMessageFormSever); receiveThread.Start(); } private new void SendMessage(string message) { byte [] buffer= Encoding.UTF8.GetBytes(message); clientSocket.SendTo(buffer,remotPoint); } public void OnSendButtonClickS() { if (buttonInput.value!=null) { buttonMessage = buttonInput.value; } else { buttonMessage = "輸入框為空!"; } SendMessage(buttonMessage); buttonInput.value = ""; } private void ReceiveMessageFormSever() { while (true) { if (clientSocket.Connected) { int length = clientSocket.Receive(bufferReceive); message = Encoding.UTF8.GetString(bufferReceive, 0, length); //ps:不要在單獨的執行緒裡面操作unity元件 } else { break; } } } }
在使用者端中同樣有一個socket物件,這個物件通過ConnetToSever方法連線到伺服器。在這裡,假如某個使用者端通過輸入框輸入文字被使用者端指令碼捕捉,它將以流的方式傳送到伺服器,伺服器接受到文字,並在伺服器端將文字群發至每個使用者端。伺服器開設了一個執行緒專門用於捕捉使用者端發來的訊息,當然,使用者端也有相應的執行緒時刻捕捉伺服器發來的訊息。訊息被使用者端捕捉到了,就可以顯示在各自的使用者端介面上了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45