Comunicación de cliente a servidor TCP

Todo lo que busco es un simple ejemplo de TCPClient / Listner en Windows Form VB.Net. Soy un novato y los ejemplos de la clase Microsoft TCPClient / Listner no son lo que estoy buscando. Todo lo que busco es que TCPClient envíe un mensaje y que un TCPListener reciba el mensaje y le envíe un mensaje “¿Recibí su mensaje?”

Un poco de ayuda sería genial. Tengo algunos códigos, pero solo para enviar mensajes al servidor y no para volver de servidor a cliente. Cualquier ayuda será muy apreciada.

La comunicación TCP es lo que se conoce como flujo basado, lo que significa que no maneja ningún paquete. Debido a esto, los mensajes que se reciben pueden ser parciales o agrupados.

Podría, por ejemplo, enviar:

Hello!

How are you?

Pero es posible que reciba:

Hello!How are you?

o:

Hello!How ar

e you?

(o algo similar)

Para solucionar esto, debe aplicar algo llamado “prefijo de longitud” . El prefijo de longitud (o el prefijo de longitud) significa que antes de enviar un mensaje, pone su longitud (cantidad de caracteres) al principio. El punto final lo leerá y luego leerá cada mensaje de acuerdo con su longitud, por lo que no habrá problemas con los mensajes parciales o los mensajes agrupados.

Esta no es la cosa más simple de hacer, pero he creado dos clases que harán todo eso por ti. Consulte los ejemplos a continuación sobre cómo usarlos para una comunicación simple basada en mensajes.

Enlace a la fuente: http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient.zip

Enlace a la fuente de C #: http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient%20CSharp.zip

Ejemplo de uso

Tenga en cuenta que en esos ejemplos el Client no se refiere al lado del cliente , sino al TcpClient .

Lado del servidor

  1. Primero declare una nueva variable para ExtendedTcpClient , y asegúrese de incluir WithEvents en la statement.

     Dim WithEvents Client As ExtendedTcpClient 
  2. Luego necesitará un TcpListener y un Timer para verificar si hay conexiones entrantes.

     Dim Listener As New TcpListener("0.0.0.0", 5555) 'Listen for any connection on port 5555. Dim WithEvents Tmr As New System.Windows.Forms.Timer 
  3. Entonces necesitas suscribirte al evento Tick del temporizador.

     Private Sub Tmr_Tick(sender As System.Object, e As System.EventArgs) Handles Tmr.Tick End Sub 

    Allí verifica las conexiones entrantes a través del método Listener.Pending() . Cuando debe aceptar una conexión, primero declara una nueva instancia de ExtendedTcpClient . La clase requiere tener un formulario como propietario, en esta aplicación Me es el formulario actual.
    Luego, utiliza el método ExtendedTcpClient.SetNewClient() con Listener.AcceptTcpClient() como argumento para aplicar el TcpClient desde el oyente. Coloque este código en el sub Tmr_Tick :

     If Listener.Pending() = True Then Client = New ExtendedTcpClient(Me) Client.SetNewClient(Listener.AcceptTcpClient()) End If 

    Ahora el cliente y el servidor están conectados entre sí.

  4. Ahora necesita suscribirse al evento PacketReceived del cliente. Crea un sub como así:

     Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles Client.PacketReceived End Sub 

    Todos los datos recibidos se presentan en una matriz de bytes. En el sub PacketReceived puede enviar el paquete recibido como texto a un TextBox . Simplemente compruebe si el encabezado del paquete es PlainText y luego puede convertir el contenido de los paquetes recibidos (que es una matriz de bytes, accedida a través de e.Packet.Contents ) en una cadena y colocarlo en el TextBox .

     If e.Packet.Header = TcpMessagePacket.PacketHeader.PlainText Then TextBox1.AppendText("Message recieved: " & System.Text.Encoding.Default.GetString(e.Packet.Contents) & Environment.NewLine) End If 

    System.Text.Encoding.Default.GetString() convertirá una matriz de bytes a texto normal.

  5. En el sub PacketReceived , también puede hacer que envíe “Mensaje recibido” al cliente.

     Dim ResponsePacket As New TcpMessagePacket(System.Text.Encoding.Default.GetBytes("Message received."), TcpMessagePacket.PacketHeader.PlainText) ResponsePacket.Send(Client.Client) 'Get the ExtendedTcpClient's underlying TcpClient. 
  6. Por último, al cerrar el formulario solo necesita desconectar el cliente.

     Private Sub ServerWindow_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing If Client IsNot Nothing Then Client.Disconnect() End Sub 

Y eso es todo por el lado del servidor.


Lado del cliente

  1. Para el lado del cliente, hará prácticamente lo mismo que en el lado del servidor, aunque no necesitará un TcpListener ni un Timer .

     Dim Client As New ExtendedTcpClient(Me) 'The current form as it's owner. 
  2. Conéctese al servidor a través de la IP y el puerto que le proporcionó al oyente.

     Client.Connect("127.0.0.1", 5555) 'Connects to localhost (your computer) at port 5555. 
  3. Ahora, si desea enviar texto al servidor, haría algo como esto (por ejemplo, en un botón):

     Dim MessagePacket As New TcpMessagePacket(System.Text.Encoding.Default.GetBytes(TextBox2.Text), TcpMessagePacket.PacketHeader.PlainText) MessagePacket.Send(Client.Client) 

    TextBox2 incluye el texto que desea enviar.

  4. Por último, deberá suscribirse al evento PacketReceived aquí también para verificar las respuestas del servidor. Allí recibes el texto tal como lo hace el servidor.

     Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles Client.PacketReceived If e.Packet.Header = TcpMessagePacket.PacketHeader.PlainText Then TextBox1.AppendText(System.Text.Encoding.Default.GetString(e.Packet.Contents) & Environment.NewLine) 'Prints for example "Message received." from the server. End If End Sub 

¡Y ahora todo debería estar funcionando!

Enlace a un proyecto de ejemplo completo (solo de cliente a servidor): http://www.mydoomsite.com/sourcecodes/TCP%20Messaging%20System.zip

Enlace al ejemplo de C #: http://www.mydoomsite.com/sourcecodes/CSharp%20TCP%20Messaging%20System.zip

Si desea agregar más encabezados a la clase (los encabezados le indican qué tipo de paquete es), simplemente abra TcpMessagePacket.vb y agregue más valores en la enumeración PacketHeader (ubicada en la región llamada Constants ).

¡Espero que esto ayude!


Captura de pantalla del proyecto de ejemplo

(Haga clic en la imagen para una resolución más grande)

Salida del proyecto de ejemplo ExtendedTcpClient