C# Implementation of Asynchronous Socket Communication Programming (1)

Introduction to Socket Communication

Socket is essentially a programming interface (API), which encapsulates TCP/IP. TCP/IP also provides an interface that programmers can use for network development. This is the Socket programming interface. A socket interface includes an ip and a corresponding port. The process of establishing a connection is as follows:
1. Server monitoring : the server-side socket does not locate a specific client socket, but is in a state of waiting for a connection to monitor the network status in real time. .
2. Client request : refers to the connection request made by the client's socket, and the target to be connected is the socket of the server.
3. Connection confirmation : When the server-side socket monitors or receives the connection request of the client-side socket, it responds to the request of the client-side socket, establishes a new thread, and connects the server-side socket. A description of the word is sent to the client, and once the client confirms this description, the connection is established. The server-side socket continues to be in the listening state and continues to receive connection requests from other client-side sockets.

Asynchronous programming

Synchronous
When performing an operation, the application must wait for the operation to complete before continuing.

Asynchronous
When performing an operation, the application can continue to execute while the asynchronous operation is executing. Essence: Asynchronous operation, a new thread is started, and the main thread is executed in parallel with the method thread.

  1. The essence of asynchrony is to open a new thread, the asynchronous thread is managed by the thread pool, and the multithreading is controlled by the programmer.
  2. The server uses asynchronous programming, which can easily accept multiple clients to connect, otherwise a new thread needs to be opened for each connected client.
  3. When writing GUI programs, using synchronous programming will cause the interface to fail to refresh and freeze. Solutions include creating new threads or using asynchronous programming.
  4. Convenient asynchronous programming is provided in C#.

Code parsing

Server

start the server

private void startServer()
        {
            ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2000);
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(ipep);
            serverSocket.Listen(10);

            // 开启异步监听端口
            serverSocket.BeginAccept(new AsyncCallback(AcceptFunc), serverSocket);
            Console.WriteLine("Waiting to connect");
        }

listen for connections

        private void AcceptFunc(IAsyncResult iar)
        {
            try
            {
                Socket s = (Socket)iar.AsyncState;                   // 异步对象,用于递归       
                Socket client = s.EndAccept(iar);             // 客户端的实例
                IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint; // 获得远端的端点,并打印远端的实例信息
                Console.WriteLine("Client:" + clientep.Address + "(" + clientep.Port + ")" + "is Connect.");

                // 异步接受消息
                client.BeginReceive(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);

                string str = "this is the 1st msg!";
                buffer = Encoding.Unicode.GetBytes(str);
                // 异步发送消息
                client.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendFunc), client);
                s.BeginAccept(new AsyncCallback(AcceptFunc), s);         //使用异步对象进行递归
            }
            catch(Exception e)
            {
                Console.WriteLine("accept Exception: "+e.Message);
            }
        }

Receive messages asynchronously

        private void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                Socket s = (Socket)ar.AsyncState;
                int length = s.EndReceive(ar);
                string message = Encoding.Unicode.GetString(receiveBuffer, 0, length);
                Console.WriteLine(message);
                //递归进行调用
                s.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), s);
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

Send messages asynchronously Send a message
every second

        private void SendFunc(IAsyncResult iar)
        {
            try
            {
                Socket s = (Socket)iar.AsyncState;
                var message = "this is manager from server!" + cnt;
                cnt++;
                buffer = Encoding.Unicode.GetBytes(message);
                Thread.Sleep(1000);
                s.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendFunc), s);
            }
            catch(Exception e)
            {
                Console.WriteLine("sendException: "+e.Message);
            }
        }

sender

start the client

        private void startConnect()
        {
            ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2000);
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
            // 异步连接                       
            clientSocket.BeginConnect(ipep, new AsyncCallback(ConnectFunc),clientSocket);
            Console.WriteLine("Waiting to connect");          
        }

Asynchronous connections
will always report exceptions when the server is not turned on. After the connection is successful, enable asynchronous reception

        private void ConnectFunc(IAsyncResult iar)
        {
            try
            {
                Socket s = (Socket)iar.AsyncState;      // 获得原始的socket               
                s.EndConnect(iar);              
                Console.WriteLine("Connected!");
                // 异步接收
                s.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), s);       
                Console.WriteLine("begin receive!");                                           
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
                // 持续的连接服务器
                Socket s = (Socket)iar.AsyncState;
                s.BeginConnect(ipep, new AsyncCallback(ConnectFunc), s);                
            }
        }

Asynchronous reception

        private void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                Socket s = (Socket)ar.AsyncState;
                int length = s.EndReceive(ar);
                string message = Encoding.Unicode.GetString(buffer, 0, length);
                Console.WriteLine(message);
                //递归进行调用,使用获得的异步对象进行递归
                s.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), s);

            }
            catch(Exception e)
            {
                Console.WriteLine("receive Exception: " + e.Message);
            }
         }

Since the console program written here is not suitable for sending, the client sending program will be implemented in the next GUI sending end.

Screenshot of program effect

write picture description here

  1. On the left is the server, which can accept multiple client connections
  2. In the middle and on the right are two clients connecting to the server and receiving messages.

For the first time in contact with C#'s Socket communication, C# provides a wealth of interface functions, which can be easily programmed. The next article will introduce the socket communication of GUI

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325766724&siteId=291194637