在客户端和服务器之间发送数据的最快方法是什么?

时间:2015-08-27 05:32:50

标签: c# wcf sockets communication asyncsocket

我想在两台服务器之间实现通信。 在客户端:一个线程准备数据并将其排入队列。第二个线程将数据出列,将其序列化并发送到服务器。 在服务器端:接收数据(字节)并将其排队。排队数据的进一步过程无关紧要。

仅用于测试目的:

  1. 我在同一台机器上运行客户端和服务器。
  2. 我通过使用长度为70字节的字符串启动records来模仿队列(我要发送的对象大约是70字节)。请参阅下面的Client->StartClient代码。
  3. 我迭代地发送数据。数据将排队很快,所以我想在它到达队列后立即发送它。我通过迭代发送来模仿它。
  4. 我使用WCF为客户端和服务器发送数据,但是花了5分钟发送70MB(每个70字节的100万条记录)。然后我决定使用Socket。我使用异步方法,它仍然花了几分钟发送70MB。 根据我的理解,在同一台机器上安装客户端和服务器,它不应该花几分钟发送70MB。最多需要几秒钟,对吧?我怎样才能加快速度呢?

    P.S。我知道你可以说“累积然后发送”。但是,我希望能够在数据进入队列后立即发送数据。

    客户端:

    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.
        private const int port = 11000;
    
        // ManualResetEvent instances signal completion.
        private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);
    
        // The response from the remote device.
        private static String response = String.Empty;
    
        private static void StartClient()
        {
            // Connect to a remote device.
            try
            {                
                IPHostEntry ipHostInfo = Dns.Resolve("MY_HOST");
                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);
                connectDone.WaitOne();
    
    //============================================================
                var records = new List<string>();                
                for (int i = 0; i < 1000000; i++)
                {
                    records.Add(new string('a', 70));
                }
    
                var serializer = new BinaryFormatter();
                var stopWatch = new Stopwatch();
                stopWatch.Start();                
                foreach (var rec in records)
                {
                    using (var ms = new MemoryStream())
                    {
                        serializer.Serialize(ms, rec);
                        var serData = ms.ToArray();
    
                        // Send test data to the remote device.
                        Send(client, serData);                                                  
                    }
                }
                stopWatch.Stop();    
    //================================================================                                      
                // Release the socket.
                client.Shutdown(SocketShutdown.Both);
                client.Close();
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)ar.AsyncState;
    
                // Complete the connection.
                client.EndConnect(ar);
    
                Console.WriteLine("Socket connected to {0}",
                    client.RemoteEndPoint.ToString());
    
                // Signal that the connection has been made.
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        private static void Send(Socket client, byte[] data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = data;// Encoding.ASCII.GetBytes(data);
    
            // Begin sending the data to the remote device.
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }
    
        private 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);
                Console.WriteLine("Sent {0} bytes to server.", bytesSent);                   
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        public static int Main(String[] args)
        {
            StartClient();
            return 0;
        }
    }
    

    服务器:

    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];
    
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
    
            // 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.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);
    
                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
    
            Console.WriteLine("\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);
            Console.WriteLine("Read {0} bytes from socket", bytesRead);
    
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                   new AsyncCallback(ReadCallback), state);
        }                
    
        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }
    

    SDF

0 个答案:

没有答案