异步服务器套接字C#继续发送消息 [英] asynchronous server socket C# continue sending messages

查看:63
本文介绍了异步服务器套接字C#继续发送消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Sockets服务器,该服务器可以异步运行,
接受一次连接的多个客户端.我从微软那里得到的
网站.
我在示例代码中对
的配置做了一些修改. IPAddress和端口.

Hi, I have the following Sockets server, which works asynchronously and
accepts multiple clients connected at once. I got it from the microsoft
website.
I made slight modifications in the example code, in the configuration of
the IPAddress and port.

1. using System;
   2. using System.Net;
   3. using System.Net.Sockets;
   4. using System.Text;
   5. using System.Threading;
   6.  
   7. // State object for reading client data asynchronously
   8. public class StateObject
   9. {
  10.     // Client  socket.
  11.     public Socket workSocket = null;
  12.     // Size of receive buffer.
  13.     public const int BufferSize = 1024;
  14.     // Receive buffer.
  15.     public byte[] buffer = new byte[BufferSize];
  16.     // Received data string.
  17.     public StringBuilder sb = new StringBuilder();
  18. }
  19.  
  20. public class AsynchronousSocketListener
  21. {
  22.  
  23.     // Incoming data from client.
  24.     public static string data = null;
  25.  
  26.     // Thread signal.
  27.     public static ManualResetEvent allDone = new
ManualResetEvent(false);
  28.  
  29.     public AsynchronousSocketListener()
  30.     {
  31.     }
  32.  
  33.     public static void StartListening()
  34.     {
  35.         // Data buffer for incoming data.
  36.         byte[] bytes = new Byte[1024];
  37.  
  38.         // Establish the local endpoint for the socket.
  39.         // The DNS name of the computer
  40.         // running the listener is "host.contoso.com".
  41.         IPAddress ipAddress =
Dns.GetHostEntry("192.168.1.33").AddressList[2];
  42.         IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 4070);
  43.  
  44.         // Create a TCP/IP socket.
  45.         Socket listener = new Socket(AddressFamily.InterNetwork,
  46.             SocketType.Stream, ProtocolType.Tcp);
  47.  
  48.         // Bind the socket to the local endpoint and listen for
incoming connections.
  49.         try
  50.         {
  51.             listener.Bind(localEndPoint);
  52.             listener.Listen(100);
  53.  
  54.             while (true)
  55.             {
  56.                 // Set the event to nonsignaled state.
  57.                 allDone.Reset();
  58.  
  59.                 // Start an asynchronous socket to listen for
connections.
  60.                 Console.WriteLine("Waiting for a connection...");
  61.                 listener.BeginAccept(
  62.                     new AsyncCallback(AcceptCallback),
  63.                     listener);
  64.  
  65.                 // Wait until a connection is made before
continuing.
  66.                 allDone.WaitOne();
  67.             }
  68.  
  69.         }
  70.         catch (Exception e)
  71.         {
  72.             Console.WriteLine(e.ToString());
  73.         }
  74.  
  75.         Console.WriteLine("\nPress ENTER to continue...");
  76.         Console.Read();
  77.  
  78.     }
  79.  
  80.     public static void AcceptCallback(IAsyncResult ar)
  81.     {
  82.         // Signal the main thread to continue.
  83.         allDone.Set();
  84.  
  85.         // Get the socket that handles the client request.
  86.         Socket listener = (Socket)ar.AsyncState;
  87.         Socket handler = listener.EndAccept(ar);
  88.  
  89.         // Create the state object.
  90.         StateObject state = new StateObject();
  91.         state.workSocket = handler;
  92.         handler.BeginReceive(state.buffer, , StateObject.BufferSize,
,
  93.             new AsyncCallback(ReadCallback), state);
  94.     }
  95.  
  96.     public static void ReadCallback(IAsyncResult ar)
  97.     {
  98.         String content = String.Empty;
  99.  
 100.         // Retrieve the state object and the handler socket
 101.         // from the asynchronous state object.
 102.         StateObject state = (StateObject)ar.AsyncState;
 103.         Socket handler = state.workSocket;
 104.  
 105.         // Read data from the client socket.
 106.         int bytesRead = handler.EndReceive(ar);
 107.  
 108.         if (bytesRead > )
 109.         {
 110.             // There  might be more data, so store the data received
so far.
 111.             state.sb.Append(Encoding.ASCII.GetString(
 112.                 state.buffer, , bytesRead));
 113.  
 114.             // Check for end-of-file tag. If it is not there, read
 115.             // more data.
 116.             content = state.sb.ToString();
 117.             if (content.IndexOf("\n") > -1)
 118.             {
 119.                 // All the data has been read from the
 120.                 // client. Display it on the console.
 121.                 Console.WriteLine("Read {0} bytes from socket. \n
Data : {1}",
 122.                     content.Length, content);
 123.                 // Echo the data back to the client.
 124.                 Send(handler, content);
 125.             }
 126.             else
 127.             {
 128.                 // Not all data received. Get more.
 129.                 handler.BeginReceive(state.buffer, ,
StateObject.BufferSize, ,
 130.                 new AsyncCallback(ReadCallback), state);
 131.             }
 132.         }
 133.     }
 134.  
 135.     private static void Send(Socket handler, String data)
 136.     {
 137.         // Convert the string data to byte data using ASCII
encoding.
 138.         byte[] byteData = Encoding.ASCII.GetBytes(data);
 139.  
 140.         // Begin sending the data to the remote device.
 141.         handler.BeginSend(byteData, , byteData.Length, ,
 142.             new AsyncCallback(SendCallback), handler);
 143.     }
 144.  
 145.     private static void SendCallback(IAsyncResult ar)
 146.     {
 147.         try
 148.         {
 149.             // Retrieve the socket from the state object.
 150.             Socket handler = (Socket)ar.AsyncState;
 151.  
 152.             // Complete sending the data to the remote device.
 153.             int bytesSent = handler.EndSend(ar);
 154.             Console.WriteLine("Sent {0} bytes to client.",
bytesSent);
 155.  
 156.             handler.Shutdown(SocketShutdown.Both);
 157.             handler.Close();
 158.  
 159.         }
 160.         catch (Exception e)
 161.         {
 162.             Console.WriteLine(e.ToString());
 163.         }
 164.     }
 165.  
 166.  
 167.     public static int Main(String[] args)
 168.     {
 169.         StartListening();
 170.         return ;
 171.     }
 172. }
 173.  




但是,按照这种方式,客户端将连接到该服务器并发送一个
信息.服务器读取它,然后断开与客户端的连接.我需要那个
客户端仍处于连接状态,并且可以继续发送许多消息,因为它
想要.
一方面,我知道我必须删除
的以下几行 SendCallBack方法,以便客户端仍处于连接状态:




However, the way it is, the client connects to this server and send a
message. The server reads it, and then disconnect the client. I need that
the client is still connected, and can continue to send many messages as it
wants.
On one hand I know that I have to remove the following lines of
SendCallBack method, so that the client is still connected:

<pre lang="midl">handler.Shutdown (SocketShutdown.Both)
handler.Close ();



无论如何,如何使客户端能够继续发送消息?做
我必须添加一个循环吗?在哪里?

谢谢!



Anyway, How can I do to enable the client to continue sending messages? Do
I must add a loop? Where?

Thanks!

推荐答案

查看标有"new"的行-您已经非常接近工作的代码了.
See the lines marked with "new" - You''re pretty close to a working piece of code already.
124.                 Send(handler, content); 
new.                 // All data received. Get next message. 
new.                 handler.BeginReceive(state.buffer,StateObject.BufferSize, 
new.                       new AsyncCallback(ReadCallback), state);
125.             } 
126.             else 
127.             { 
128.                 // Not all data received. Get more. 
129.                 handler.BeginReceive(state.buffer,StateObject.BufferSize, 
130.                       new AsyncCallback(ReadCallback), state);



正如您得出的结论-不要在Send方法中关闭连接,请等到客户端发送关闭"消息.

问候
Espen Harlinn



And as you concluded - don''t close the connection in the Send method, wait until the client sends a "close" message.

Regards
Espen Harlinn


不,请不要使用循环.使用计时器创建一种轮询机制.
No dont use a loop. Creating a polling sort of a maechanism using a timer.


这篇关于异步服务器套接字C#继续发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆