C#網絡編程學習(4)---Socket Tcp進階之 使用異步循環接收客戶端連接和信息


1、方法介紹

BeginAccept(AsyncCallback callback, object state);
異步開始監聽客戶端連接。

  1. callback為一個委托,在成功接收客戶端連接時調用委托方法。
  2. 向委托方法中傳遞的參數

**EndAccept (IAsyncResult result);** 結束監聽客戶端連接,一般在委托中成功接收連接后使用。 1. **result**:它存儲此異步操作的狀態信息以及任何用戶定義數據。 返回。使用**result.AsyncState** 可以接收傳遞過來的參數。
**BeginReceive (byte[] buffer, int offset, int size, SocketFlags flag, AsyncCallback callback, object state);** 異步接收服務器發送來的數據 1. 存儲接收的數據 2. 從buffer哪開始存儲數據 3. 要接受最大的字節數 4. SocketFlags 值的按位組合 5. 接收成功后調用的委托方法 6. 要傳遞的參數

2、服務器端

namespace Tcp服務器端
{
    class Program
    {
        /// <summary>
        /// 接收客戶端發送數據數組
        /// </summary>
        static byte[] data = new byte[1024];

        static void Main(string[] args)
        {
            StartServerAsync();
        }

        static void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
            serverSocket.Bind(point);
            serverSocket.Listen(100);

            //異步監聽客戶端連接
            serverSocket.BeginAccept(AcceptCallBack,serverSocket);

            Console.ReadKey();
        }
        /// <summary>
        /// 接收到客戶端連接時調用
        /// </summary>
        static void AcceptCallBack(IAsyncResult ar)
        {
            Console.WriteLine("一個客戶端連接了進來\n");
            Socket serverSocket = null;
            try
            {
                //接收傳遞過來的main中的serverSocket
                serverSocket = ar.AsyncState as Socket;
                //結束接收,返回接收到的clientSocket
                Socket clientSocket = serverSocket.EndAccept(ar);

                clientSocket.Send(Encoding.UTF8.GetBytes("你好呀。。。客戶端"));
                //異步開始監聽客戶端傳遞數據
                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);  //從頭開始存,最大數量,none,接收到客戶端后執行的回調函數,要傳遞的參數(會被傳遞給回調函數)

                //繼續處理下一個客戶端的連接,相當於一個偽遞歸
                serverSocket.BeginAccept(AcceptCallBack, serverSocket);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                if (serverSocket != null)
                    serverSocket.Close();
            }
        }
        /// <summary>
        /// 接收到客戶端發送的數據時調用
        /// </summary>
        static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = null;
            try
            {
                clientSocket = ar.AsyncState as Socket;
                int count = clientSocket.EndReceive(ar);

                //正常關閉的情況
                if (count == 0)
                {
                    Console.WriteLine("一個客戶端正常斷開了連接");
                    clientSocket.Close();
                    return;
                }
                Console.WriteLine("接收到數據:" + Encoding.UTF8.GetString(data, 0, count));

                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);  //從頭開始存,最大數量,none,接收到客戶端后執行的回調函數,要傳遞的參數
            }
            catch (Exception e)
            {
                //非正常關閉的情況
                Console.WriteLine(e);
                if (clientSocket != null)
                    clientSocket.Close();
            }
        }

        
    }
}

3、客戶端

namespace Tcp客戶端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
            clientSocket.Connect(point);

            byte[] data = new byte[1024];
            int length = clientSocket.Receive(data);
            Console.WriteLine(Encoding.UTF8.GetString(data, 0, length));

            //循環向服務器發送數據
            while (true)
            {
                string s = Console.ReadLine();
                //輸入c正常退出,直接按×異常退出
                if (s == "c")
                {
                    clientSocket.Close();
                    return;
                }
                clientSocket.Send(Encoding.UTF8.GetBytes(s));
            }
            

            Console.ReadKey();

        }
    }
}

4、效果

服務器可以接收多個客戶端連接
多個客戶端都可以向服務器發送數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM