vb.net - Comunicación del cliente TCP al servidor
winforms client-server (1)
Todo lo que estoy buscando es un ejemplo simple de TCPClient / Listner en Windows Form VB.Net. Soy un novato y los ejemplos de clase TCPClient / Listner de Microsoft no son lo que estoy buscando. Todo lo que busco es que el TCPClient envíe un mensaje y que un TCPListener reciba el mensaje y envíe un mensaje "¿Recibí su mensaje"?
Un poco de ayuda sería genial. Tengo algunos códigos, pero es solo para enviar un mensaje al servidor y no de regreso del servidor al cliente. Cualquier ayuda será muy apreciada.
La comunicación TCP es lo que se llama 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 puede recibir:
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, debe colocar su longitud (cantidad de caracteres) al principio. Esto puede ser leído por el punto final que luego leerá cada mensaje de acuerdo con su longitud, por lo que no habrá problemas con mensajes parciales o mensajes agrupados.
Esto no es lo más simple, pero he creado dos clases que harán todo eso por ti. Vea 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
-
Primero declare una nueva variable para
ExtendedTcpClient
y asegúrese de incluirWithEvents
en la declaración.Dim WithEvents Client As ExtendedTcpClient
-
Luego, necesitará un
TcpListener
y unTimer
para verificar las 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
-
Luego debe suscribirse 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 delExtendedTcpClient
. La clase requiere tener un formulario como propietario, en esta aplicaciónMe
es el formulario actual.
Luego, utiliza el métodoExtendedTcpClient.SetNewClient()
conListener.AcceptTcpClient()
como argumento para aplicar elTcpClient
desde el oyente. Pon este código en el subTmr_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í.
-
Ahora debe suscribirse al evento
PacketReceived
del cliente. Crea un submarino 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
PacketReceived
puede enviar el paquete recibido como texto a unTextBox
. Simplemente verifique si el encabezado del paquete esPlainText
y luego puede convertir el contenido de los paquetes recibidos (que es una matriz de bytes, a los que se accede a través dee.Packet.Contents
) en una cadena y ponerlo en elTextBox
.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. -
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.
-
Por último, al cerrar el formulario solo necesita desconectar al 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
-
Para el lado del cliente, hará más o menos lo mismo que el lado del servidor, aunque no necesitará un
TcpListener
ni unTimer
.Dim WithEvents Client As New ExtendedTcpClient(Me) ''The current form as its owner.
-
Conéctese al servidor a través de la IP y el puerto que le ha dado al oyente.
Client.Connect("127.0.0.1", 5555) ''Connects to localhost (your computer) at port 5555.
-
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. -
Por último, deberá suscribirse al evento
PacketReceived
aquí también para verificar las respuestas del servidor. Allí recibes texto al igual que 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 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 mayor resolución)