SoloCodigo

CLR: .Net / Mono / Boo / Otros CLR => C# => Mensaje iniciado por: elRitualK en Jueves 22 de Julio de 2010, 02:21

Título: C# Servidor Socket Asincronico Multicliente
Publicado por: elRitualK en Jueves 22 de Julio de 2010, 02:21
Buenas, tengo el siguiente servidor de Sockets, que trabaja de forma asincronica y acepta multiples clientes conectados a la vez. El mismo lo saque de la web de microsoft.

Al codigo del ejemplo le realize unas pequenias modificaciones en la parte de la configuracion de la IPAddress y el Puerto.

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

Ahora bien, asi como esta, el cliente se conecta a este servidor y envia un mensaje. El servidor lo lee, y luego desconecta al cliente. Yo necesito que el cliente siga conectado, y pueda seguir enviando cuantos mensajes quiera.

Por un lado se que tengo que remover las siguientes lineas del metodo SendCallBack, para que el cliente siga conectado:

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

En fin, como puedo hacer para que el cliente pueda seguir enviando mensajes? Hay que agregar un bucle? Donde?

Gracias!