http://www.developer.com/

Back to article

Using Winsock


November 19, 2002

A few years ago, I was called in to a hectic call-centre - the head honcho had a problem.

Ironically, it was communication. Even though they had phones coming out of their ears (boom, boom), the people in this company simply couldn't talk to each other.

Half of his staff were constantly on the telephone. The other half were temporary employees that didn't know each other's names and moved chairs quicker than a bunch of seven-years olds at a birthday party.

The problem? When one of the workers had a query on an account and needed to question the last person dealing with it — they didn't know where to start. Who was who?

The solution came as a simple package I very originally christened Talk — essentially a more personalised version of ICQ or MSN Messenger. And it worked.

When an individual started work at a desk, they logged in. When they finished, they logged out. Somewhere in the middle, users could send messages to each other, have a digital chat even send files to and fro.

But how did it all work? By using the Winsock control. And this brief guide will demonstrate how to use it yourself, starting with a quick run-through of the basics, through to tips on setting up a chat session — plus handy links on how to initiate file transfers. We'll even cover how you can play Big Brother, and remotely control computers.

So without further ado, prepare to enter the wonderful world of Winsock...

We'll start our look at Winsock by creating a mini messaging application.

It's not going to be all-out bells and whistles, but you'll be able to send a message from computer A to computer B and it'll give you a feel for how the 'Winsock control' works.

So let's get started:

  • Launch Visual Basic
  • Click 'Project', 'Components'
  • Check the 'Microsoft Winsock Control'
  • Hit OK
  • Draw out the Winsock control onto your Form

Now, the Winsock control is the key to this article. It allows you to easily communicate over a network.

  • Add a Text Box to your Form, changing its Name to 'txtAddress'
  • Add another Text Box to your Form, changing its Name to 'txtMessage'

The first Text Box will hold the 'address' of the computer you want to send your message to. And the second box will hold the actual message itself. This will be sent "through" the Winsock control we added just a few seconds ago.

  • Add a Command Button to your Form
  • Insert the following code behind your button:
Winsock1.RemoteHost = txtAddress.TextWinsock1.RemotePort = 1000Winsock1.ConnectDo Until Winsock1.State = sckConnectedDoEvents: DoEvents: DoEvents: DoEventsLoopWinsock1.SendData (txtMessage.Text)Winsock1.Close
Let's take a few seconds out to explain this code:
Winsock1.RemoteHost = txtAddress.TextWinsock1.RemotePort = 1000

These first two lines of code simply tell the Winsock control which computer it should 'connect' to.

The RemoteHost can either be a computer name or IP address.

Top Tip: An IP address is a series of four numbers separated by dots, such as 102.42.35.32. It's just a numeric address that uniquely identifies your computer. Everyone on your network will have a unique IP address and every time you connect to the Internet, your machine is automatically assigned an IP address and no-one else on the Net will have the same address as yourself. It's sort of like a real address information sent to that address only gets to yourself, no-one else. To find out your IP address, click Start, Programs, MS DOS Prompt, type 'IPCONFIG' then press return

That second line of code simply sets the 'RemotePort'. This can be pretty much any number and you can imagine it as a frequency on a radio dial. Here, you're tuning into 1000 FM on the other computer and preparing to broadcast.

Winsock1.ConnectDo Until Winsock1.State = sckConnected   DoEvents: DoEvents: DoEvents: DoEventsLoop

This chunk of code simply attempts to connect to the remote computer and loops around until it has that connection.

Top Tip: It's worth noting that if a connection isn't made because, say, the other computer has just crashed or cannot be found, this code will just continue looping round and round. When an error occurs in Winsock, the State property equals sckError (9) so you may want to add a little code to handle that here.

Winsock1.SendData (txtMessage.Text)

And finally, this last piece of code sends your message across to that other computer.

So, that's our message-sending program, the client, finished. Now let's build the other end the receiving application...

If you've ever attempted to build a real-life radio receiver (I have... D'OH!) - you'll be pleased to know that programming one in Visual Basic is so much easier.

Let's get on with it:

  • Launch another instance of Visual Basic
  • Add the Winsock control
  • Behind the Form_Load event, add this code:
Winsock1.LocalPort = 1000Winsock1.Listen

This tells your Winsock control to listen in to 1000 FM for any incoming messages.

Next, let's add a little code behind the Winsock control itself. There are two main events we'll be dealing with here, ConnectionRequest and DataArrival. Let's cover these now:

  • Add the following code behind the ConnectionRequest event of the Winsock control:
If Winsock1.State <> sckClosed Then Winsock1.CloseWinsock1.Accept requestID

This code will run when our program receives a connection request, such as from our message-sending client attempting to do a Winsock1.Connect.

Firstly, this code ensures the Winsock control is 'closed' in other words, makes sure it isn't connected to another computer. Then it accepts the connection request and the two computers are magically 'linked'.

  • Add the following code behind the DataArrival event of the Winsock control:
Dim strIncoming As StringWinsock1.GetData strIncomingMsgBox strIncoming

This event fires up when information is arriving when someone does a 'Winsock1.SendData' - following a successful connection. The first line creates a variable to store the incoming information. The second line slots the incoming information into the variable via the GetData method. After this you can do what you want with the data I chose to simply display it in a message box.

Top Tip: After you've retrieved the data via the GetData method, it disappears from memory. If you want to look at it without having it vanish from memory, use the PeekData method.

And that's it! You've created both a program to send a message (the client) and a program to receive a message (the server). Of course, you could merge them both together to both send and receive, but we'll cover that in a couple of minutes. For now, let's test our project:

  • Press F5 in each copy of Visual Basic to start each application
  • In your message sending application, fill in the two Text Boxes the first should contain the computer name or IP address of the machine you are sending the message to, the second should contain your actual message

Top Tip: If you're running both the sending and receiving program on the same computer, you can use the IP address 127.0.0.1 this number simply refers to your computer.

Another Top Tip: It's always more stable using an IP address to locate a computer, than a machine name. But how can you find out a users IP address? Do what ICQ does! When your users log on, check out the Winsock's LocalIP property, which contains the users unique IP address. Then register this with some central database. When someone wants to send a message, lookup the user, find their IP address, then send them a message. When they log off, remove their details from your database. That's how the biggies do it!

  • Press the Command Button in your message sending program
  • Flip back to your receiving program

Do you see a box holding your message text? You should do! If so, congratulations you've just sent your first message via the Winsock control.

And even if you're experimenting with this on your one computer remember, it can work anywhere. You could be sending messages right across the office, via your company network, or even right across the globe thanks to the Internet.

Now, let's briefly review the major code snippets we've looked at here in printable format!

Let's briefly review the raw code for building a simple messaging program with the Winsock control. All of this code is based around what we have discovered already, with a few slight enhancements:

To Open a Connection

If Winsock1.State <> sckClosed Then Winsock1.Close

Winsock1.RemotePort = 1008Winsock1.RemoteHost = "127.0.0.1"Winsock1.Connect

To Wait until Connected

Do Until Winsock1.State = sckConnectedDoEvents: DoEvents: DoEvents: DoEventsIf Winsock1.State = sckError ThenMsgBox "Problem connecting!"Exit SubEnd IfLoop

To Listen Out for Communication

Winsock1.LocalPort = 1008Winsock1.Listen

To Accept an Incoming Connection Request

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)    If Winsock1.State <> sckClosed Then Winsock1.Close    Winsock1.Accept requestIDEnd Sub

To Send Data

Winsock1.SendData ("Data Goes Here")

To Receive Incoming Data

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)        Dim strIncoming As StringWinsock1.GetData strIncomingx = strIncoming        End Sub

So far, we've created a program that sends messages. And a program that receives messages.

But the send program can't receive. And the receive program can't send.

Now, I may not be an Einstein but the world pretty much survives on two-way communication. And even though most introductions don't usually delve beyond the code we've explored so far, let's be honest ICQ wouldn't have a membership base of ninety million if you could only send messages one way.

So in order to implement this functionality, I've created a quick 'template' application that allows you to both send and receive. You can download that here go on, have a play around and see what you can do!

And for all the groovy guys and gals printing this article, here's a dump of the core code, complete with basic error handling. All objects, such as Text Boxes have been given 'English' names to make the code more readable:

Private Sub Form_Load()On Error GoTo PortErr' Listen out for any possible connection' requests or data, etc.Winsock1.LocalPort = 202Winsock1.Listen' This uses port 201. To work, this program' must be run on two separate computers' - otherwise there will be a conflict with' two programs trying to access port 201Exit Sub    PortErr:    MsgBox "Another program is using port 201. This " & _    "may be because you're running another copy " & _    "of this program on the same computer. " & _"Unfortunately, this only works over a real " & _"network, either an office setup or the Internet. " & _"When two computers try to 'listen in' to the same " & _"part of a computer, one of them receives an error. " & _"I am alas the unlucky soul. Sorry! Here's an idea " & _"though - alter my Form_Load source code, changing the " & _"LocalPort property to 202 instead of 201. This should " & _"allow you to test both programs on the same machine!", _         vbCritical            EndEnd SubPrivate Sub cmdSendMessage_Click()    If Winsock1.State = sckConnected Then                ' If connected, just send the data                Winsock1.SendData (txtOutgoingMessage.Text)            Else            If MsgBox("You are not connected. " & _            "Connect to " & txtAddress.Text & "?", _            vbYesNo + vbQuestion) = vbYes Then                        ' Connect to the remote machine                        Winsock1.Close            Winsock1.RemotePort = 201            Winsock1.RemoteHost = txtAddress.Text            Winsock1.Connect                            ' Wait until full connection is made                            Do Until Winsock1.State = sckConnected                DoEvents: DoEvents: DoEvents: DoEvents                If Winsock1.State = sckError Then                    MsgBox "Problem connecting!"                    Exit Sub                End If            Loop                    ' Send the data                    Winsock1.SendData (txtOutgoingMessage)                Else                    Call MsgBox("OK - not connected!", vbInformation)                End If        End If        End SubPrivate Sub Winsock1_ConnectionRequest(ByVal requestID As Long)    ' Accept an incoming connection request        If Winsock1.State <> sckClosed Then Winsock1.Close    Winsock1.Accept requestIDEnd SubPrivate Sub Winsock1_DataArrival(ByVal bytesTotal As Long)        ' Display incoming data        Dim strIncoming As String    Winsock1.GetData strIncoming    txtIncomingMessage.Text = strIncoming    End Sub

Now that you've established two-way communication, the world's your oyster. You could do absolutely diddly anything.

One thing you might want to have a look at is chat sessions. Now if you put a little imagination into it, you can turn the instant messaging functionality you have right now into a chat session, no problemo.

Think about it: every time data arrives via the DataArrival event, you could add it to a colourful Text Box. And each time your user taps something in to send, this could also be added to the box. And there you have it your chat session!

If you fancy playing around with this, try grabbing my download from the previous page and making a few teensy-weensy alterations:

  • Extend Form1 a little
  • Add a Text Box to the newly expanded area
  • Changed the Text Box properties as so:

Name - txtChatLog

Font - Arial, Bold, 9

ForeColor - Dark Red

Locked - True

This Text Box will be your chat log. Next, we're going to add code that inserts text into the chat box every time a message is either sent or received.

  • Insert the following code behind your Form:
Public Sub AddToChatBox(Speaker As String, Sentence As String)    txtChatLog.Text = txtChatLog.Text & _        (Speaker & ": " & vbTab & "" & Sentence) & _        vbCrLfEnd Sub
  • Add the following code to the end of the Winsock DataArrival event:
AddToChatBox "Remote", strIncoming
  • Add the following code after the SendData methods under the Command Button:
AddToChatBox "You", strOutgoingMessage.Text

And that's it! Every time a message is sent back and forth, it gets added to the log creating a virtual chat session. Corr blimey sneaky or what?

Top Tip: If you're wanting to knock-up a multi-user chat room, check out this site: http://www.freevbcode.com/ShowCode.Asp?ID=137, which demonstrates using multiple Winsock connections. You can even create your own mini ICQ with this good-looking download http://www.planetsourcecode.com/xq/ASP/txtCodeId.6520/lngWId.1/qx/vb/scripts/ShowCode.htm from Evan Sims.

Sending files via the Winsock is, alas, a little more difficult than plain ol' messages.

The problem is, the Winsock control can only work with small strings of text. So the only way to transfer a file is to break it down into manageable chunks and send those across to the other party as individual chunks. The receiving computer would then need to stick these back together again to recreate the original file.

Not quite a thirty-second jobby, but still relatively easy. Erm, but I'm going to give it a miss 'cause you can find demos of this technique already at:

But, ya know, the Winsock control doesn't only have to be used for messaging and file sending. Oh no...

Now, you may have heard about a sneaky lil' program called Back Orifice.

Created (and rather awfully christened) by hackers last year, this tool hit the headlines as it allows computer A to control computer B and do all sorts of weird and wonderful things.

As an example, a nerdy teenager from Outer Mongolia may take control of your mouse, shut down your machine, browse your computer files or take a 'snapshot' of your screen.

But how? Surprisingly enough, via Winsock programming.

Instead of simply displaying messages that come in via the Winsock control, don't forget you could also interpret them as commands. So you could have a lil' widget running on computer B that just sits idle, waiting to be told what to do.

Then your supercool computer A could send it something like a 'TakeScreenshot' command upon which your program on computer B could take a snapshot of the screen using the API, then send it back to you. Or perhaps you could send a 'ShutDown' command, if you want to turn the machine off.

Sure, it might sound a bit spooky and Big Brother-ish, but it does have a few genuine uses (apart from simply spying on your fellow colleagues, in search of juicy blackmail material). Imagine being able to instantly turn off computers for all those forgetful office workers. Or being able to send out an instant message to all employees. Or checking for naughty-naughty games on the hard drive. Or whatever.

Well, here are a few links for you to pursue just in case you decide to turn all power crazy and control your office the digital way:

In this brief introduction to the Winsock control, we started out building a simple one-way messaging application.

Within a few minutes, we'd moved this to being a bi-directional instant messaging tool, then looked at chat sessions, file transfers and even considered how we can use the Winsock control to send 'commands' to our client machines. On the way, we picked up a bundle of tips, which taught us how to 'think big' and use this newfound knowledge to create our own lil' ICQ.

If you're looking to take your Winsock work further, try checking out comprehensive tutorial from VBWeb

I hope this introduction has given you a taste of the possibility behind Winsock.

And so until the next time, this is Karl Moore, signing off wishing you all a pleasant evening, wherever you are in the world.

Night night!

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date