C# Socket之TCP服務(wù)器

需要引用using System.Net.Sockets; using System.Net;兩個(gè)命名空間;

namespace TcpServer  //服務(wù)器
{
    class Program
    {
        public static List<Client> clientList = new List<Client>();
       
        static void Main(string[] args)
        {
            Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//創(chuàng)建socket對(duì)象
            tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.145"), 8090));//綁定IP和申請(qǐng)端口

            tcpServer.Listen(100);//設(shè)置客戶(hù)端最大連接數(shù)
            Console.WriteLine("服務(wù)器已啟動(dòng),等待連接.........");
            while (true)//循環(huán)等待新客戶(hù)端的連接
            {
                Socket clientSocket = tcpServer.Accept();
                Console.WriteLine((clientSocket.RemoteEndPoint as IPEndPoint).Address+"已連接");
                Client client = new Client(clientSocket);
                clientList.Add(client);
            }
        }
        public static void BroadcastMessage(string message, Client clientSocket)//這個(gè)函數(shù)用來(lái)廣播接收到的客戶(hù)端消息  參數(shù)1為消息,參數(shù)2為消息來(lái)源(客戶(hù)端)
        {
            var onConnectedList = new List<Client>();//用來(lái)存儲(chǔ)已斷開(kāi)服務(wù)器連接的客戶(hù)端

            foreach (var client in clientList)//遍歷已經(jīng)存儲(chǔ)的客戶(hù)端
            {
                if (clientSocket == client)//如果該客戶(hù)端是消息來(lái)源,則不重復(fù)發(fā)送消息給該客戶(hù)端
                {
                    continue;
                }
                if (client.Connected)//判斷該客戶(hù)端的狀態(tài)
                {
                    client.SendMessage(client.ip + ":" + message);//
                }
                else//把已斷開(kāi)連接的客戶(hù)端放到數(shù)組中
                {
                    onConnectedList.Add(client);
                }
            }
            foreach (var temp in onConnectedList)//廣播完之后從存儲(chǔ)已連接客戶(hù)端集合中移除掉已斷開(kāi)連接的客戶(hù)端
            {
                clientList.Remove(temp);
            }
        }
    }
}
namespace TcpServer  
{
    class Client
    {
        private Socket clientSocket;
        private Thread t;
        public string ip = "";
        private byte[] data = new byte[1024];
        public Client(Socket socket)
        {
            clientSocket = socket;
            ip = (clientSocket.RemoteEndPoint as IPEndPoint).Address.ToString();//獲取客戶(hù)端的ip
            t = new Thread(ReceiveMessage);//開(kāi)啟線(xiàn)程執(zhí)行循環(huán)接收消息
            t.Start();
        }
        private void ReceiveMessage()//接收消息
        {
            int length = 0;//初始化消息的長(zhǎng)度
            while (true)//循環(huán)接收消息
            {
                length = clientSocket.Receive(data);//獲取存放消息數(shù)據(jù)數(shù)組的長(zhǎng)度
                if (clientSocket.Poll(10, SelectMode.SelectRead))//????
                {
                    clientSocket.Close();
                    break;
                }
                if (length != 0)//判斷是否有數(shù)組內(nèi)是否存放消息數(shù)據(jù)
                {
                    string message = Encoding.UTF8.GetString(data, 0, length);//Byte轉(zhuǎn)為string
                    Program.BroadcastMessage(message, this);//廣播給其他客戶(hù)端
                    Console.WriteLine("來(lái)自" + (clientSocket.RemoteEndPoint as IPEndPoint).Address + ":" + message);//輸出到服務(wù)器控制臺(tái)
                    length = 0;//歸0
                }
            }
        }
        public void SendMessage(string message)//發(fā)送消息
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientSocket.Send(data);
        }
        public bool Connected//獲取該客戶(hù)端的狀態(tài)
        {
            get { return clientSocket.Connected; }
        }
    }
}
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 此文章將記錄我在C# Winform 開(kāi)發(fā)過(guò)程中遇到的問(wèn)題及相關(guān)知識(shí)技術(shù)點(diǎn) ,方便自己以后查閱..... 博客原文...
    遇見(jiàn)_c256閱讀 3,644評(píng)論 1 21
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評(píng)論 19 139
  • 一、 為什么需要命名空間(問(wèn)題提出) 命名空間是ANSIC++引入的可以由用戶(hù)命名的作用域,用來(lái)處理程序中 常見(jiàn)的...
    IvanRunning閱讀 2,430評(píng)論 0 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,094評(píng)論 25 709
  • 煮溫酒,論銀劍,醉后相歡。吞青梅,思白棋,歡后相念。記閑日,飲苦茶,念后相知。撲燭火,放簾幕,知后相守。
    星河沸點(diǎn)閱讀 295評(píng)論 0 1

友情鏈接更多精彩內(nèi)容