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

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

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

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

1、服務器端有兩個類:

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);//監(jiān)聽是否有客戶端發(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);//將每個新創(chuàng)建的連接通信放于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;
? ? ? ? ? ? //由于消息是不斷發(fā)送的,需要多次進行處理。這里開一個線程,專門用來處理消息。
? ? ? ? ? ? mesManageTherad = new Thread(MessageSendFromClient);
? ? ? ? ? ? mesManageTherad.Start();
? ? ? ? }

? ? ? ? private void MessageSendFromClient()
? ? ? ? {
? ? ? ? ? ? //開啟的線程一直檢測客戶端客戶端發(fā)過來的消息
? ? ? ? ? ? while (true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //判斷連接是否斷開, ?SelectMode.SelectRead讀狀態(tài)模式。
? ? ? ? ? ? ? ? //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("客戶端發(fā)送過來的消息:"+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;
? ? ? ? ? ? }
? ? ? ? }

? ? }
}

服務器端邏輯:

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

2.客戶端

客戶端是在Unity中使用NGUI插件簡單開發(fā)的一個聊天界面。把腳本掛在NGUI控件上即可。客戶端主要負責顯示消息,發(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 = "";//默認為空串


? ? // 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);
? ? ? ? //因為是一直在準備接受的狀態(tài),所以開啟一個線程來負責處理接受消息
? ? ? ? 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方法連接到服務器。在這里,假如某個客戶端通過輸入框輸入文本被客戶端腳本捕捉,它將以流的方式發(fā)送到服務器,服務器接受到文本,并在服務器端將文本群發(fā)至每個客戶端。服務器開設了一個線程專門用于捕捉客戶端發(fā)來的消息,當然,客戶端也有相應的線程時刻捕捉服務器發(fā)來的消息。消息被客戶端捕捉到了,就可以顯示在各自的客戶端界面上了。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論