All I\'m looking for is a simple TCPClient/Listner example on Windows Form VB.Net. I\'m a newbie and Microsoft TCPClient/Listner class examples are not what I am looking for. All I am looking is for the TCPClient to send a message and for a TCPListener to get the message and to send a message back \"I got your message\" ?
A little help would be great. I have some codes, but is only to send message to server and not back from server to client..
Any help will be very appreciated..
TCP communication is what\'s called stream-based, which means it doesn\'t handle any packets. Due to this messages that are received can be partial or lumped together.
You could for example send:
Hello!
How are you?
But you might receive:
Hello!How are you?
or:
Hello!How ar
e you?
(or something similar)
To fix this you must apply something called \"length-prefixing\". Length-prefixing (or length prefixing) means that before you send a message, you put it\'s length (amount of characters) in the beginning of it. This can then be read by the endpoint which will then read each message according to it\'s length, thus there will be no problems with partial messages or messages lumped together.
This is not the most simple thing to do, but I\'ve created two classes that will do all that for you. See the examples below on how to use them for simple message-based communication.
Link to source: http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient.zip
Link to C# source : http://www.mydoomsite.com/sourcecodes/ExtendedTcpClient%20CSharp.zip
Example usage
Note that in those examples Client
does not refer to the client side, but to the TcpClient.
Server side
First declare a new variable for ExtendedTcpClient
, and be sure to
include WithEvents
in the declaration.
Dim WithEvents Client As ExtendedTcpClient
Then you will need a TcpListener
and a Timer
to check for incoming connections.
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
Then you need to subscribe to the timer\'s Tick
event.
Private Sub Tmr_Tick(sender As System.Object, e As System.EventArgs) Handles Tmr.Tick
End Sub
In there you check for incoming connections via the Listener.Pending()
method. When you are to accept a connection you first declare a new
instance of the ExtendedTcpClient
. The class requires to have a
form as it\'s owner, in this application Me
is the current form.
Then you use the ExtendedTcpClient.SetNewClient()
method with
Listener.AcceptTcpClient()
as it\'s argument to apply the
TcpClient
from the listener. Put this code in the Tmr_Tick
sub:
If Listener.Pending() = True Then
Client = New ExtendedTcpClient(Me)
Client.SetNewClient(Listener.AcceptTcpClient())
End If
Now the client and server are connected to each other.
Now you need to subscribe to the PacketReceived
event of the
client. Create a sub like so:
Private Sub Client_PacketReceived(sender As Object, e As ExtendedTcpClient.PacketReceivedEventArgs) Handles Client.PacketReceived
End Sub
All received data are presented in an array of bytes.
In the PacketReceived
sub you can output the received packet as text into a TextBox
. Just check if the packet header is PlainText
and then
you can convert the received packets contents (which is an array of
bytes, accessed via e.Packet.Contents
) to a string and put it in
the 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()
will convert a byte array to normal text.
In the PacketReceived
sub you can also make it send \"Message received\" to the client.
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.
Lastly, when closing the form you just need to disconnect the client.
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
And that\'s it for the server side.
Client side
For the client side you will do pretty much the same as the server side, though you won\'t be needing a TcpListener
nor a Timer
.
Dim Client As New ExtendedTcpClient(Me) \'The current form as it\'s owner.
Connect to the server via the IP and port you\'ve given the listener.
Client.Connect(\"127.0.0.1\", 5555) \'Connects to localhost (your computer) at port 5555.
Now if you want to send text to the server you\'d do something like this (in for example a button):
Dim MessagePacket As New TcpMessagePacket(System.Text.Encoding.Default.GetBytes(TextBox2.Text), TcpMessagePacket.PacketHeader.PlainText)
MessagePacket.Send(Client.Client)
TextBox2
includes the text you want to send.
Lastly, you will need to subscribe to the PacketReceived
event here too to check for responses from the server. In there you receive text just like the server does.
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
And now everything should be working!
Link to a complete example project (only client-to-server): http://www.mydoomsite.com/sourcecodes/TCP%20Messaging%20System.zip
Link to C# example: http://www.mydoomsite.com/sourcecodes/CSharp%20TCP%20Messaging%20System.zip
If you want to add more headers to the class (the headers indicates to you what type of packet it is), just open TcpMessagePacket.vb
and add more values in the PacketHeader
enum (located in the region called Constants
).
Hope this helps!
Screenshot from the example project
(Click the image for larger resolution)