C# socket異步通訊


Server:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TCP_Server
{
    internal class Program
    {
        private static readonly byte[] Buffer = new byte[1024];
        private static int _count;

        private static void Main()
        {
            WriteLine("Server is ready.", ConsoleColor.Green);

            //①創建一個新的Socket,這里我們使用最常用的基於TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //②將該socket綁定到主機上面的某個端口
            //方法參考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 7788));

            //③啟動監聽,並且設置一個最大的隊列長度
            //方法參考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(3);

            //④開始接受客戶端連接請求
            //方法參考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
            Console.ReadLine();
        }

        // 客戶端連接成功
        public static void ClientAccepted(IAsyncResult ar)
        {
            //設置計數器
            _count++;
            var socket = ar.AsyncState as Socket;
            //這就是客戶端的Socket實例,我們后續可以將其保存起來
            if (socket != null)
            {
                var client = socket.EndAccept(ar);
                
                //客戶端IP地址和端口信息
                IPEndPoint clientipe = (IPEndPoint)client.RemoteEndPoint;

                WriteLine(clientipe + " is connected,total connects " + _count, ConsoleColor.Yellow);

                //接收客戶端的消息
                client.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
            }

            //准備接受下一個客戶端連接請求
            if (socket != null) socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
        }

        // 接收客戶端的信息
        public static void ReceiveMessage(IAsyncResult ar)
        {
            var socket = ar.AsyncState as Socket;
            //客戶端IP地址和端口信息
            if (socket != null)
            {
                IPEndPoint clientipe = (IPEndPoint)socket.RemoteEndPoint;
                try
                {
                    //方法參考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                    var length = socket.EndReceive(ar);
                    //讀取出來消息內容
                    var message = Encoding.UTF8.GetString(Buffer, 0, length);
                    //輸出接收信息
                    WriteLine(clientipe + " :" + message, ConsoleColor.White);
                    //服務器發送消息
                    socket.Send(Encoding.UTF8.GetBytes("Server received data"));
                    //接收下一個消息
                    socket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
                }
                catch (Exception)
                {
                    //設置計數器
                    _count--;
                    //斷開連接
                    WriteLine(clientipe + " is disconnected,total connects " + (_count), ConsoleColor.Red);
                }
            }
        }

        public static void WriteLine(string str, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine("[{0:MM-dd HH:mm:ss}] {1}", DateTime.Now, str);
        }
    }
}

  Client:

using System;
using System.Net.Sockets;
using System.Text;

namespace TCP_Client
{
    internal class Program
    {
        private static readonly byte[] Buffer = new byte[1024];

        private static void Main()
        {
            try
            {
                //①創建一個Socket
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //②連接到指定服務器的指定端口
                socket.Connect("127.0.0.1", 7788);

                WriteLine("Client: Connect to server success!", ConsoleColor.White);

                //③實現異步接受消息的方法 客戶端不斷監聽消息
                socket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);

                //④接受用戶輸入,將消息發送給服務器端
                while (true)
                {
                    var message = Console.ReadLine();
                    if (message != null)
                    {
                        var outputBuffer = Encoding.UTF8.GetBytes(message);
                        socket.BeginSend(outputBuffer, 0, outputBuffer.Length, SocketFlags.None, null, null);
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLine("Client: Error " + ex.Message, ConsoleColor.Red);
            }
            finally
            {
                Console.Read();
            }
        }

        // 接收信息
        public static void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                var socket = ar.AsyncState as Socket;

                //方法參考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                if (socket != null)
                {
                    var length = socket.EndReceive(ar);
                    var message = Encoding.ASCII.GetString(Buffer, 0, length);
                    WriteLine(message, ConsoleColor.White);
                }

                //接收下一個消息
                if (socket != null)
                {
                    socket.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
                }
            }
            catch (Exception ex)
            {
                WriteLine(ex.Message, ConsoleColor.Red);
            }
        }

        public static void WriteLine(string str, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine("[{0:MM-dd HH:mm:ss}] {1}", DateTime.Now, str);
        }
    }
}

  


免責聲明!

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



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