1. 程式人生 > >通訊聊天室 Socket 同步

通訊聊天室 Socket 同步

通訊Socket

using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;//socket的空間
using System.Net;//IP和埠引用的空間
using System.Threading;


namespace TCP伺服器端  //先發再收
{
    class Program
    {
        static Queue<string> Quexiaoxi = new Queue<string>();
        static Dictionary<Socket, string> clientSocketDic = new Dictionary<Socket, string>();
        static void Main(string[] args)
        {
            StartServerSync();
        }
        static void StartServerSync()
        {
            //先建立一個伺服器端Socket
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //  127.0.0.1Any(萬能本機IP)
            IPAddress iPAddress = IPAddress.Parse("192.168.53.28");
            IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 88);//80埠是內建http的(特殊埠)
            //繫結IP埠
            serverSocket.Bind(iPEndPoint);
            //處理連結佇列客戶端的個數 0代表不限制
            serverSocket.Listen(0);
            Console.WriteLine("伺服器成功開啟");

            //開啟執行緒管理客戶連結
            Thread childThread = new Thread(myAcceptThread);
            childThread.Start(serverSocket);
            childThread.IsBackground = true;

            //開啟管理群發執行緒
            Thread processThread = new Thread(myProcessThread);
            processThread.Start();
            processThread.IsBackground = true;
        }//同步
        static void myProcessThread()
        {
            while (true)
            {
                if (Quexiaoxi.Count > 0)
                {
                    string readString = Quexiaoxi.Dequeue();
                    Console.WriteLine("正在群發:{0}", readString);
                    byte[] snedBytes = Encoding.UTF8.GetBytes(readString);
                    foreach (Socket client in clientSocketDic.Keys)
                    {
                        client.Send(snedBytes);
                    }
                }
                Thread.Sleep(200);
            }
        }
        static void myAcceptThread(object socket)
        {
            Socket serverSocket = socket as Socket;
            while (true)
            {
                try
                {
                    Socket clientSocket = serverSocket.Accept();
                    string msg = "歡迎" + clientSocket.RemoteEndPoint.ToString();
                    Console.WriteLine(msg);

                    Quexiaoxi.Enqueue(msg);
                    clientSocketDic.Add(clientSocket, clientSocket.RemoteEndPoint.ToString());

                    Thread clientThread = new Thread(myClientThread);
                    clientThread.Start(clientSocket);
                    clientThread.IsBackground = true;

                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    serverSocket.Close();
                    break;
                }
            }



        }
        static void myClientThread(object socket)
        {
            Socket clientSocket = socket as Socket;
            try
            {
                int count = 0;
                while (true)
                {
                    byte[] dataBuffer = new byte[1024];//快取的位元組陣列  要足夠大
                    count = clientSocket.Receive(dataBuffer);
                    if (count == 0)
                    {
                        string tip = string.Format("客戶端{0}斷開連線", clientSocketDic[clientSocket]);
                        Console.WriteLine(tip);
                        Quexiaoxi.Enqueue(tip);
                        clientSocket.Close();
                        break;
                    }
                    else
                    {
                        string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);//接受訊息
                        Console.WriteLine("接收到客戶端{0}:{1}", clientSocket.RemoteEndPoint.ToString(), msg);//列印
                        Quexiaoxi.Enqueue(clientSocketDic[clientSocket] + msg);//存入佇列
                    }
                }
            }
            catch (Exception e)
            {
                string tip = string.Format("{0}因為異常({1})退出", clientSocketDic[clientSocket], e.Message);
                Console.WriteLine(tip);
                clientSocketDic.Remove(clientSocket);//從字典中移除
                Quexiaoxi.Enqueue(tip);//加入佇列(最後一句話)
                clientSocket.Close();
            }
        }