欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#基于Socket實(shí)現(xiàn)簡(jiǎn)單聊天室功能

 更新時(shí)間:2022年02月12日 09:26:39   作者:Csoap994  
這篇文章主要為大家詳細(xì)介紹了C#基于Socket實(shí)現(xiàn)簡(jiǎn)單聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

因?yàn)檫@段時(shí)間在學(xué)習(xí)Socket,所以就試著寫(xiě)了一個(gè)簡(jiǎn)單的聊天室。主要分為服務(wù)器端和多個(gè)客戶端。利用服務(wù)器端作數(shù)據(jù)中轉(zhuǎn)站,實(shí)現(xiàn)消息群發(fā)。

1、服務(wù)器端有兩個(gè)類(lèi):

using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace 聊天室_Socket_TCP_服務(wù)器端
{
? ? 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);//監(jiān)聽(tīng)是否有客戶端發(fā)起連接
? ? ? ? ? ? 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);//將每個(gè)新創(chuàng)建的連接通信放于client類(lèi)做通信
? ? ? ? ? ? ? ? ? ? clients.Add(client);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? Console.ReadKey();
? ? ? ? }
? ? }
}
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace 聊天室_Socket_TCP_服務(wù)器端
{
? ? /// <summary>
? ? /// 利用該類(lèi)和客戶端做通信
? ? /// </summary>
? ? class Client
? ? {
? ? ? ? public Socket clientSocket;
? ? ? ? private Thread mesManageTherad;?
? ? ? ? private byte[] bufffer=new byte[20];

? ? ? ? public Client(Socket soc)
? ? ? ? {
? ? ? ? ? ? clientSocket = soc;
? ? ? ? ? ? //由于消息是不斷發(fā)送的,需要多次進(jìn)行處理。這里開(kāi)一個(gè)線程,專(zhuān)門(mén)用來(lái)處理消息。
? ? ? ? ? ? mesManageTherad = new Thread(MessageSendFromClient);
? ? ? ? ? ? mesManageTherad.Start();
? ? ? ? }

? ? ? ? private void MessageSendFromClient()
? ? ? ? {
? ? ? ? ? ? //開(kāi)啟的線程一直檢測(cè)客戶端客戶端發(fā)過(guò)來(lái)的消息
? ? ? ? ? ? while (true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //判斷連接是否斷開(kāi), ?SelectMode.SelectRead讀狀態(tài)模式。
? ? ? ? ? ? ? ? //poll已斷開(kāi)返回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("客戶端發(fā)送過(guò)來(lái)的消息:"+mes);
? ? ? ? ? ? ? ? ? ? //廣播消息出去給每個(gè)客戶端
? ? ? ? ? ? ? ? ? ? Program.CastMessageTOAllConnetedClients(mes);//對(duì)CastMessage的一層封裝
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? /// <summary>
? ? ? ? /// Send messages to Clients
? ? ? ? /// </summary>
? ? ? ? public void CastMessage(string message)
? ? ? ? {
? ? ? ? ? ? byte[] data = Encoding.UTF8.GetBytes(message);
? ? ? ? ? ? clientSocket.Send(data);
? ? ? ? }

? ? ? ? /// <summary>
? ? ? ? /// 判斷是否斷開(kāi)連接
? ? ? ? /// </summary>
? ? ? ? public bool Conneted
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return clientSocket.Connected;
? ? ? ? ? ? }
? ? ? ? }

? ? }
}

服務(wù)器端邏輯:

這里的服務(wù)器主要負(fù)責(zé)建立連接,接受客戶端消息,廣播客戶端發(fā)來(lái)的消息。
服務(wù)器通過(guò)socket對(duì)象綁定服務(wù)器IP和相應(yīng)端口號(hào)(端口號(hào)自己開(kāi),沒(méi)有被其他軟件占用就好),通過(guò)Listen監(jiān)聽(tīng)和服務(wù)器socket對(duì)象的Accept方法捕捉連接到服務(wù)器的客戶端socket,將捕捉到的客戶端socket放入List集合中方便統(tǒng)一管理和后面的消息群發(fā)。
關(guān)于捕捉到的客戶端socket的邏輯處理放在了Client類(lèi)中統(tǒng)一管理。
Client類(lèi)將收到客戶端的消息進(jìn)行接受,在Client中開(kāi)啟一個(gè)線程用于不斷得檢測(cè)是否有新消息從客戶端發(fā)送過(guò)來(lái),若有消息發(fā)送過(guò)來(lái)則通過(guò)CastMessageTOAllConnetedClients方法(對(duì)socket對(duì)象的Send方法的封裝)發(fā)送給每一個(gè)客戶端。

2.客戶端

客戶端是在Unity中使用NGUI插件簡(jiǎn)單開(kāi)發(fā)的一個(gè)聊天界面。把腳本掛在NGUI控件上即可??蛻舳酥饕?fù)責(zé)顯示消息,發(fā)送消息,接收消息。

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 = "";//默認(rèn)為空串


? ? // Use this for initialization
? ? void Start () {
? ? ? ? ConnetToSever(_ipAdress, _port);//與服務(wù)器建立連接
? ? }

? ? // 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);
? ? ? ? //因?yàn)槭且恢痹跍?zhǔn)備接受的狀態(tài),所以開(kāi)啟一個(gè)線程來(lái)負(fù)責(zé)處理接受消息
? ? ? ? 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 = "輸入框?yàn)榭眨?;
? ? ? ? }
? ? ? ? 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:不要在單獨(dú)的線程里面操作unity組件
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

在客戶端中同樣有一個(gè)socket對(duì)象,這個(gè)對(duì)象通過(guò)ConnetToSever方法連接到服務(wù)器。在這里,假如某個(gè)客戶端通過(guò)輸入框輸入文本被客戶端腳本捕捉,它將以流的方式發(fā)送到服務(wù)器,服務(wù)器接受到文本,并在服務(wù)器端將文本群發(fā)至每個(gè)客戶端。服務(wù)器開(kāi)設(shè)了一個(gè)線程專(zhuān)門(mén)用于捕捉客戶端發(fā)來(lái)的消息,當(dāng)然,客戶端也有相應(yīng)的線程時(shí)刻捕捉服務(wù)器發(fā)來(lái)的消息。消息被客戶端捕捉到了,就可以顯示在各自的客戶端界面上了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論