tcp套接字异步通信

tcp socket asynchronous communication

`

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;

namespace ServerSocket
{
    class Class1
    {
        public class StateObject
        {
            // Client  socket.
            public Socket workSocket = null;
            // Size of receive buffer.
            public const int BufferSize = 1024;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();
        }

        public class AsynchronousSocketListener
        {
            // Thread signal.
            public static ManualResetEvent allDone = new ManualResetEvent(false);

            public AsynchronousSocketListener()
            {
            }

            public static void StartListening()
            {
                // Data buffer for incoming data.
                byte[] bytes = new Byte[1024];

                // Establish the local endpoint for the socket.
                // The DNS name of the computer
                // running the listener is "host.contoso.com".
                //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
                IPAddress ipAddress = IPAddress.Parse("192.168.1.89");
                //IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8095);

                // Create a TCP/IP socket.
                Socket listener = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);

                // Bind the socket to the local endpoint and listen for incoming connections.
                try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(100);

                    while (true)
                    {
                        // Set the event to nonsignaled state.
                        allDone.Reset();

                        // Start an asynchronous socket to listen for connections.
                        MessageBox.Show("Waiting for a connection...");
                        listener.BeginAccept(
                            new AsyncCallback(AcceptCallback),
                            listener);
                        //TcpListener tcpListener = new TcpListener(ipAddress, 8095);
                        //tcpListener.Start();
                        // Wait until a connection is made before continuing.
                        allDone.WaitOne();
                    }

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }

                MessageBox.Show("\nPress ENTER to continue...");
                Console.Read();

            }

            public static void AcceptCallback(IAsyncResult ar)
            {
                // Signal the main thread to continue.
                allDone.Set();

                // Get the socket that handles the client request.
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);

                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
            }

            public static void ReadCallback(IAsyncResult ar)
            {
                String content = String.Empty;

                // Retrieve the state object and the handler socket
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;

                // Read data from the client socket. 
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There  might be more data, so store the data received so far.
                    state.sb.Append(Encoding.ASCII.GetString(
                        state.buffer, 0, bytesRead));

                    // Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        // All the data has been read from the 
                        // client. Display it on the console.
                        MessageBox.Show(string.Concat("Read bytes from socket. \n Data :",
                            content.Length, content));
                        // Echo the data back to the client.
                        Send(handler, content);
                    }
                    else
                    {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReadCallback), state);
                    }
                }
            }

            private static void Send(Socket handler, String data)
            {
                // Convert the string data to byte data using ASCII encoding.
                byte[] byteData = Encoding.ASCII.GetBytes(data);

                // Begin sending the data to the remote device.
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), handler);
            }

            private static void SendCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object.
                    Socket handler = (Socket)ar.AsyncState;

                    // Complete sending the data to the remote device.
                    int bytesSent = handler.EndSend(ar);
                    MessageBox.Show(string.Concat("Sent bytes to client.", bytesSent));

                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }


            //public static int Main(String[] args)
            //{
            //    StartListening();
            //    return 0;
            //}
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Windows.Forms;

namespace ClientSocket
{
    class Class1
    {
        public class StateObject
        {
            // Client socket.
            public Socket workSocket = null;
            // Size of receive buffer.
            public const int BufferSize = 256;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();
        }

        public class AsynchronousClient
        {
            // The port number for the remote device.
            public const int port = 8095;

            // ManualResetEvent instances signal completion.
            //set the initial state to signaled
            public static ManualResetEvent connectDone =
                new ManualResetEvent(false);
            public static ManualResetEvent sendDone =
                new ManualResetEvent(false);
            public static ManualResetEvent receiveDone =
                new ManualResetEvent(false);

            // The response from the remote device.
            public static String response = String.Empty;

            public static void StartClient(string Msg)
            {
                // Connect to a remote device.
                try
                {
                    // Establish the remote endpoint for the socket.
                    // The name of the 
                    // remote device is "host.contoso.com".
                    //IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
                    IPAddress ipAddress = IPAddress.Parse("192.168.1.89");

                    //IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
                    //IPAddress ipAddress = ipHostInfo.AddressList[0];
                    IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

                    // Create a TCP/IP socket.
                    Socket client = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);

                    // Connect to the remote endpoint.
                    client.BeginConnect(remoteEP,
                        new AsyncCallback(ConnectCallback), client);
                    //TcpListener tcpListener = new TcpListener(ipAddress, port);
                    //tcpListener.Start();
                    connectDone.WaitOne();//Blocks the current thread until the current System.Threading.WaitHandle receives a signal.

                    // Send test data to the remote device.
                    Send(client, Msg + "<EOF>");
                    sendDone.WaitOne();

                    // Receive the response from the remote device.
                    Receive(client);
                    receiveDone.WaitOne();

                    // Write the response to the console.
                    MessageBox.Show("Response received", response);

                    // Release the socket.
                    //client.Shutdown(SocketShutdown.Both);
                    //client.Close();
                   // client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
                }
                catch (SocketException e)
                {
                    MessageBox.Show(e.Message);
                }
            }

            public static void ConnectCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object.
                    Socket client = (Socket)ar.AsyncState;//Gets a user-defined object that qualifies or contains information about an 
                    //asynchronous operation.

                    // Complete the connection.
                    client.EndConnect(ar);//Ends a pending asynchronous connection request.

                    MessageBox.Show(string.Concat("Socket connected to ",
                        client.RemoteEndPoint.ToString()));

                    // Signal that the connection has been made.
                    connectDone.Set();
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }

            public static void Receive(Socket client)
            {
                try
                {
                    // Create the state object.
                    StateObject state = new StateObject();
                    state.workSocket = client;

                    // Begin receiving the data from the remote device.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }

            public static void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the state object and the client socket 
                    // from the asynchronous state object.
                    MessageBox.Show("Receivecallback");
                    StateObject state = (StateObject)ar.AsyncState;
                    Socket client = state.workSocket;

                    // Read data from the remote device.
                    int bytesRead = client.EndReceive(ar);

                    if (bytesRead > 0)
                    {
                        // There might be more data, so store the data received so far.
                        state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                        // Get the rest of the data.
                        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                            new AsyncCallback(ReceiveCallback), state);
                    }
                    else
                    {
                        // All the data has arrived; put it in response.
                        if (state.sb.Length > 1)
                        {
                            response = state.sb.ToString();
                        }
                        // Signal that all bytes have been received.
                        receiveDone.Set();
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }

            public static void Send(Socket client, String data)
            {
                // Convert the string data to byte data using ASCII encoding.
                byte[] byteData = Encoding.ASCII.GetBytes(data);

                // Begin sending the data to the remote device.
                client.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), client);
            }

            public static void SendCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object.
                    Socket client = (Socket)ar.AsyncState;

                    // Complete sending the data to the remote device.
                    int bytesSent = client.EndSend(ar);
                    MessageBox.Show(string.Concat("Sent bytes to server.", bytesSent.ToString()));
                    SocketConnected(client);
                    // Signal that all bytes have been sent.
                    sendDone.Set();
                    MessageBox.Show("Send Callback");

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
            public static bool SocketConnected(Socket s)
            {
                bool part1 = s.Poll(1000, SelectMode.SelectRead);
                bool part2 = (s.Available == 0);
                if (part1 && part2)
                    return false;
                else
                    return true;
            }

            //public static int Main(String[] args)
            //{
            //    StartClient();
            //    return 0;
            //}


        }
    }
}

`
我用 C# windows 应用程序尝试了异步客户端和服务器通信模式。

我测试了来自不同系统的服务器应用程序和我自己系统上的客户端应用程序。

一旦我 运行 两个应用程序同时我就可以收到消息。之后我必须重新启动这两个应用程序才能发送另一条消息。但我需要它可以一直发送数据而无需重新启动应用程序。

我看到的一个方面是服务器在向客户端发送数据后关闭套接字连接。这意味着客户端需要启动另一轮连接序列以进行数据交换(您提到的重新启动应用程序)。让服务器在交换数据时保持连接(不要 close)。

                handler.Shutdown(SocketShutdown.Both);
                handler.Close();