This tutorial will show how to create a P2P (Peer To Peer) connection with another user, and transfer data in the form of strings. This is only a basic tutorial, but the logic can be extended to anything. I've already used this to create an Instant Messager, a few multi player online games, and some other basic information exchange programs.
First things first, let's start a form to work with. Obviously you don't need all or any of these items on your form, and you may even want to add more (such as a field to enter an IP address). Create a form and add 1 Button, 1 TextBox, and 1 Timer. Make the textbox big enough to type in. For the timer set the interval property in the properties box to 1 and the enabled property to True. It should look something like this:
Now let's take a look at those codes. Bring up the Code window for Form 1. We are going to need to import a few namespaces in the area before Public Class Form1.
Imports System.Net.Sockets Imports System.Threading Imports System.IO Public Class Form1
The System.Net.Sockets namespace will allow us to make and listen to connections from and with other users.
The System.Threading namespace will allow us to do several things at the same time without interfering with one another
The System.IO namespace will allow us to send and receive information over our connection
Next we will need a few variables
Dim Listener As New TcpListener(65535) Dim Client As New TcpClient Dim Message As String = ""
The variable Listener is a TcpListener that listens for incoming connections (data someone is sending you) at a specific port. A port is just the gateway that you want information to flow through. It doesn't really matter what port you use, as long as it's not already being used. There are 65,535 ports to choose from. The lower numbers are used more often and the higher are usually open, so you will be more likely to find an open port if you pick a high number. We are going to use the last port, for the sake of it.
The variable Client is a TcpClient, which is basically the other computer that you are sending information.
The variable Message is just a String to hold incoming messages. We are going to make it empty when the form first starts, because there is no message yet.
When Form1 first loads we want to start a separate thread to take care of some repetitive tasks that would otherwise freeze your application.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim ListThread As New Thread(New ThreadStart(AddressOf Listening)) 'Creates the thread ListThread.Start() 'Starts the thread End Sub
This part should be pretty easy to understand. Dim ListThread creates the thread. AddressOf is the Address (sub) that you want the thread to start working on. And ListThread.Start() starts the thread.
Obviously the sub Listening doesn't exist yet, so we need to create it. The only thing this sub needs to do is start our TcpListener (remember it was called Listener?)
Private Sub Listening() Listener.Start() End Sub
The reason we added this to the thread is because if we didn't it would eventually freeze up your application.
Now we need to do something when the TcpListener hears a connection.
NOTE: At this part I use the timer. I have yet been unsuccessful in creating a loop that will listen for a connection without causing problems somewhere. If you know of a way, it will work here just fine I'm sure, and maybe you could even help me out?
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If Listener.Pending = True Then Message = "" Client = Listener.AcceptTcpClient() Dim Reader As New StreamReader(Client.GetStream()) While Reader.Peek > -1 Message = Message + Convert.ToChar(Reader.Read()).ToString End While MsgBox(Message, MsgBoxStyle.OkOnly) End If
What this does is checks 1000 times a second (if the timer interval is set to 1) to see if the TcpListener heard a connection. If it does, then it proceeds to collect the message.
First we have to make sure variable Message is empty. No message has come in yet remember? Then we need to accept the connection (sort of like answering the phone). We'll use the TcpClient variable that we created earlier (Client) to hold the client (other computer).
Next we need to start a stream for the data to come in. So we create a StreamReader that can read the stream. The argument for the StreamReader is what stream to read. We initiate the stream from the client with Client.GetStream() as the argument.
Now it's time to read from the stream. Since we can't read a messages that isn't there, we need to make sure that there is something to read. To do this we will read one character at a time, but we will use Reader.Peek() to peek ahead one space and make sure there is a letter there, which will return the index of the next letter. If there is no letter it will return -1, therefore, as long as Reader.Peek() comes back greater than -1 we can keep going.
Next we want to save the message we are receiving in our String variable Message. Since we are only getting one letter at a time we want to add each letter onto the end of what is already there. So we use Message = Message + the next letter. And finally we read the next letter with Reader.Read() This letter is going to come in as machine data that is pretty much gibberish to people, so we will have to convert it to readable characters first.
Also, we want to see the message so we are just going to display it in a message box.
The last thing we need to do to complete our P2P connection, is send a message to someone, which we will do when we click on Button1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Client = New TcpClient("127.0.0.1", 65535) Dim Writer As New StreamWriter(Client.GetStream()) Writer.Write(TextBox1.Text) Writer.Flush() End Sub
Once again we are going to use the variable Client to establish a connection with the other computer. But this time we need to determine who we are sending the data to, and what port we are using. Since this is a demo we are just going to connect to ourselves (and yes, talk to ourselves), by using the IP 127.0.0.1 (the universal home address in case you didn't know). You may want to add a TextBox to type in a different address and use that as the IP to connect to (something along the lines of TextBox2.Text). Then we want use the same port to make sure the info gets where it's going.
Now let's create a stream to write our data on. Create a StreamWrite that can write to streams. Like the StreamReader, it has an argument of which stream to write to, and we will use Client.GetStream() again. After that we write the text from TextBox1 into the stream. And when it's all done we flush it, which is, for all intensive purposes, like flushing a toilet to make everything go down the pipe where it needs to go.
Oh and make sure you close the code with:
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Listener.Stop() End Sub End Class
You should be able to run the application now, and send yourself messages. I've included a textfile with the typed code for you to look at if you need help. Have fun!
For the record:
- StreamWriter and StreamReader are part of the System.IO namespace
- TcpClient and TcpListener are part of the System.Net.Socket namespace
- Thread is part of the System.Threading namespace
Number of downloads: 8592
This post has been edited by the_hangman: 29 November 2006 - 06:06 AM