News Button Separator General Button Separator   Tutorials Page Side Products Page Side Gallery   Button Forum Button About
Tutorials


GamerTheGreat.com - The Best Flash Games/Animations Portal for Great Gamers. Are you Great enough?



 

Visual Basic 6 Winsock Tutorial - Part 2 (Multi-user chat)

by VirusFree

 

 

Tutorial Description :This is the part 2 of the winsock tutorial for visual basic 6.
In this part i will show you not just how to connect a client with
a server, but how to create a multiple connection receiving server,
and how to make a real chat network , something like IRC

 
Who should read this :This tutorial targets the beginners in Visual Basic 6.
This is part 2 so if you know nothing about winsock then
you must first read the part 1
Although i will try to explain everything asthoroughly as i can,
basic knowledge of visual basic 6 or generallyprogramming is required.

 
What is Winsock :The Winsock we are going to use is an ActiveX that we can add in our
visual basic program so we can use it's features. When using the internet
( like from a web browser ) a lot of things happen behind the scenes.
Packets are constructed by the soft wares that are then being send through
routers and others are being received by your Operating System and analyzed
by the application that send it. In order to do such complicated things a lot
of in formation like headers, packet size ,hashes ,packet order and many more
are required to create the packets. You WILL NOT have to deal with that stuff
using the Winsock control from vb. Continue reading to see just how easy it is
to effectively use Winsock.

 
What do you need :For this tutorial you will only need a computer running Windows ,
Microsoft Visual Basic 6, and the will to learn!

 
What will this tutorial teach you :In this tutorial i am going to show you how to create a simple multi user chat program.
The chat program will be just a server and a client, that you can connect
from the internet ( or LAN ) and simply exchange text messages, but this server
can receive more than one clients and create a simple chat channel

 
What are servers and clients : To connect any 2 programs, you need at least one server and one client.
The server will be the program that opens the ports on the hosting machine
and receive the connections while the client is called the program
thatconnects to the remote host. For example, when you connect to Google
withyour firefox (or  internet explorer), your browser plays the role of the client
that connects to the hosts that are running at Google. Most common is for the
servers to be able to receive more than one connections from different clients
These is called multithreaded socket servers , and this is what I am going to show
you in this tutorial

 

 
 

 Download the Tutorials Example Source Code  


 
 
Writting the Client
 
The client is actually the exact same used in part 1 , since changes have been made (changed a bit one line )
you can read how to write it at part 1,Here is the Link
 





 



Writting the Server
 
The server in we want to create is much more complex than part 1, since this one will be able to handle
multiple client , and be responsible to distribute data to clients.

If you don't know how to create the simple server i suggest you read Part 1  first.

 
Ok, Here is the Server Form


 
Now before i get into it , i must first tell you some basic things about control arrays.
Control arrays is a very nice feature of VB that allows you to have many controls and handle them
just like you would use an array. Control can be anything ( labels, command buttons, picture boxes , winsock , etc)
and you can create new controls at runtime, unload them , or use them by saying ControlName(ControlIndex)
where ControlName is then name of your control eg. label1 , pic1 and so on , and ContolIndex is a number
which represent the current control in the control array

I made a simple control demonstration program to see and test how to use them
You can download it from here

Note : To create a control array, select a control , for instance a label , and copy it ,
           then try to paste it back to the form. Visual Basic will then ask you
          "You already have a control named 'xxxxxx'. Do you want to create a control array?"
          and click yes


A lot of hard work is behind everything you see in this site. So if you like it you can help us to keep
the site as free and open to the public as possible by making a donation (of any amount)

Ok now back to the winsock thing...

The logic behind this is to create a server that will be listening on a port. When a connection is requested
by a client , instead of assigning the connection to the listening socket , a new socket will be created , and
the connection will be assigned to it , thus keeping the listening socket listening for requests to come...

 
In the project we will have a global variable SocketCounter that will count how many sockets we made
and what will be the index of the new one...
That isn't really necessary because you can always get control count
using the controls array .count function ( see the control array example above )
 
 
First the listening button code....
 

Private Sub bntListen_Click()

On Error Resume Next
'close and unload all previous sockets
For n = 1 To SocketCounter
     sock1(n).Close
     Unload sock1(n)
Next

On Error GoTo t

'sock1(0) is the name of our Winsock ActiveX Control

sock1(0).Close 'we close it in case it listening before


'txtPort is the textbox holding the Port number
sock1(0).LocalPort = txtPort'set the port we want to listen to
'( the client will connect on this port too)



sock1(0).Listen'Start Listening


txtLog = "Listening on Port " & txtPort

Exit Sub
t:
MsgBox "Error : " & Err.Description, vbCritical
End Sub
 
 



With the server we need to accept the request from the client before the connection is completed
To do that we use the sock1_ConnectionRequest that is triggered when a client tries to connect on our host.
the connection will be completed only if we accept the request. ( command is bellow with bold fonts )
But remember, we must create a NEW winsock control and assign the connection to it, otherwise it you
assign the connection to the sock with index 0 (which is our listening sock ) then it will stop listening
for connection so clients will not be able to connect to the server

Bellow is the code that handles the connection request
 
 

Private Sub sock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
'txtLog is the textbox used as our log.

'this event is triggered when a client try to connect on our host
'we must accept the request for the connection to be completed,
'but we will create a new control and assign it to that, so
'sock1(0) will still be listening for connection but
'sock1(SocketCounter) , our new sock , will handle the current
'request and the general connection with the client


'increase counter
SocketCounter = SocketCounter + 1

'this will create a new control with index equal to SocketCounter
Load sock1(SocketCounter)

'with this we accept the connection and we are now connected to
'the client and we can start sending/receiving data

sock1(SocketCounter).Accept requestID

'add to the log
txtLog = "Client Connected. IP : " & sock1(0).RemoteHostIP & " , Client Nick : Client" & sockcounter & vbCrLf

'tell our client his assigned nickname
sock1(SocketCounter).SendData "Your Nick is ""Client" & SocketCounter & """"

End Sub
 




 
Next we need to write the DataArrival event.
What is important to remember for this, is that when a client send a text string to the server ,
it is not meant for the server, but all other clients that are currently connected.
( remember we are trying to create an IRC like chatroom )
So when server get some data from the client ,  it need to redistribute it to all connected clients
(also informing them who send the text )

Ok here is the code for the dataarrival event
 

Private Sub sock1_DataArrival(IndexAs Integer, ByVal bytesTotalAs Long)
'This is being trigger every time new data arrive
'we use the GetData function which returns the data that winsock is holding


Dim dat As String       'where to put the data

sock1(Index).GetData dat, vbString      'writes the new data in our string dat ( string format )

'add the new message to our chat buffer
txtLog = txtLog & "Client" & Index & " : " & dat & vbCrLf

'now the client says something, wich arrived at the server...
'the server must now redistibute this message to all other connected
'clients...

On Error Resume Next      'Error Handler
For n = 1To SocketCounter
      IfNot n = Index Then      'we don't want to send the msg back to the sender :)
            If sock1(n).State = sckConnected Then      'if socket is connected
                 sock1(n).SendData "Client" & Index & " : " & dat
            End If
      End If
Next

End Sub

 
 
 
Ok! those are the most crucial parts, there is also theError and Close events but there is nothing special about them,
you can see them in the example source

 


 Download the Tutorials Example Source Code  

 


 
This tutorial was written by VirusFree.

Thank you for reading  it and please excuse my English

For any problems or question please don't hesitate to post them in our forums
and i ( or anyone else who can answer them ) will reply as soon as possible
 
 
Keywords : Visual Basic, winsock, winsock connections, vb, multiuser chat, irc, server, client, winsock tutorial ,
                   visual basic winsock tutorial.
 
 




    Comments
 

 Neko - 2/1/2007 5:35:05 PM
   
 Quite an error in that program =\ Here we go.

[code:1:fdd8aed328]rivate Sub sock1_DataArrival(IndexAs Integer, ByVal bytesTotalAs Long)
'This is being trigger every time new data arrive
'we use the GetData function which returns the data that winsock is holding

Dim dat As String 'where to put the data

sock1(Index).GetData dat, vbString 'writes the new data in our string dat ( string format )

'add the new message to our chat buffer
txtLog = txtLog & "Client" & Index & " : " & dat & vbCrLf

'now the client says something, wich arrived at the server...
'the server must now redistibute this message to all other connected
'clients...
On Error Resume Next 'Error Handler
For n = 1To SocketCounter
IfNot n = Index Then 'we don't want to send the msg back to the sender :)
If sock1(n).State = sckConnected Then 'if socket is connected
sock1(n).SendData "Client" & Index & " : " & dat
End If
End If
Next

End Sub[/code:1:fdd8aed328]

With that, what it is doing is taking the Index (first client) and the n (newest client) and letting them talk. Not all at once. Heres an example:

Client1 connects and talk. The server receives Client1 (Index)'s text and sends it to Index and N (If you arent N) Right?

Client2 Now connects, giving him the amazing title of Index (because he is the newest) =] and talks. Once again the server sends it to Index, and N. (The old index turns into N) So it sends it to them fine.

Now client3 connects. and talks. And receives the title of index. Making Client2 (n) and Client1 have no title at all so when the server receives either N or Index's text, it sends it to n and index. So since client1 has no name, he is an outcast and can not cfommunicate to anyone =[

I will leave it up to you to fix if you want. Good Luck =] [/code]
 
 
   
 

 VirusFree - 2/1/2007 8:54:43 PM
   
 well... i looked the code again and again and i can't find any errors

i also tested the examples with 5 clients connected to the server and
everything was fine....

have you tested the example code?

from your description i thing you got it wrong...
let me try to clear things up...

First... when a new client connects .. he gets for nickname "client" and his
index in the servers sock array..
so first client is "client1" second "client2" ,"client3" and so on...

this number that will be assigned to the new client is not store in variable
N ... but in the global variable SocketCounter (first line in servers code )

ok... for our example let's assume we have 4 clients connected...
"client1","client2","client3" and "client4"

when "client1" send a string , the sock1_DataArrival events will be
triggered, and the parameter Index will hold the index of the socket
that got the msg .. so Index will be equal to 1

but client1 doesn't really want the server to get the msg ... but all the other
clients... so server has to re-sent it to all connected socks...

SocketCounter is our global variable that hold how many connect clients
we have ( in our example is equal to the value 4)

so we must do a for .. to loop through all the sockets ( clients ) and send
the msg that we got from client1

so...
[color=blue:82ad02f321]For n = 1 To SocketCounter [/color:82ad02f321]
will loop from 1 to 4 .. each time n will hold a value from 1 to 4...

so.. first loop.. n equals to 1 ..
but 1 (client1) is the one that send the msg.. we don't want to resend it
to him...
that is what [color=blue:82ad02f321]If Not n = Index Then
[/color:82ad02f321] does...
n equals to 1 ... index equals to 1 .. and because we have the Not operator
in front .. the if will not be executed...

so we get to loop 2 ( N= 2)
[color=blue:82ad02f321]If sock1(n).State = sckConnected Then[/color:82ad02f321]
here we check if client2 is actually connected...
(trying to send something to a not connected socket will just give us
an error ) ... so since client2 is connected we move to the next command
which is
[color=blue:82ad02f321]sock1(n).SendData "Client" & Index & " : " & dat [/color:82ad02f321]
now in this loop the n is equal to 2 . .. so what we do here is to send
to client2 the string that client1 send ( is stored in the dat variable)
but we also tell it where the msg came from...
[color=green:82ad02f321]"Client" & Index & " : "[/color:82ad02f321]
Index is equal to 1 (remember that client1 triggered the event )
(let's assume client1 said 'hello world')
so the string that will arrive back to client2 is
"Client1 : hello world"
and all client2 has to do is to show this message...


as we move to loop 3 ... (N is equal to 3 now )
[color=blue:82ad02f321]sock1(n).SendData "Client" & Index & " : " & dat [/color:82ad02f321]
will send the same string "Client1 : hello world" to client3..
and client3 will show that

and the same will be send to client4 at the next loop


try also the example code.. if that works ok

i hope i made this clear enough to understand
 
 
   
 

 Neko - 2/4/2007 12:27:24 AM
   
 It may be my version or something. I used your example code, then used you idea for making one. Ive made a few multi user chats, but in a different way. It may be me though. So if it works for you fine, then good job =] I will try to figure out as to why this is not working for me =\
 
 
   
 

 soumik - 5/25/2007 12:32:36 PM
   
 those two applications are pretty good and i want to thank virus free for that. both the applications are working properly and absolutely free from error.
 
 
   
 

 macomal - 6/6/2007 4:50:06 AM
   
 Could i use encryption in sending data thro-and-fro the server/client in winsock?
 
 
   
 

 VirusFree - 6/11/2007 3:59:38 AM
   
 yeah sure... encrypt the data before sending them ( at the client ) and decrypt them after the arrive ( at your server )
 
 
   
 

 thatguypulkit - 7/2/2007 12:11:42 PM
   
 hi.... I am having the same problem as neko.... I don't know how it is possible... Can you help me??? I will paste here my complete code.... can you tell me what's wrong??? Note one thing that in my server's code if I add a msgbox command when I send data to each user... then it works fine... when I don't, only the newest client gets the message... then if I add another client to join the server... then all the unreceived messages are received at once on the client...
 
 
   
 

 thatguypulkit - 7/2/2007 12:13:31 PM
   
 'chat client's code


Private Sub Clientsock_DataArrival(ByVal bytesTotal As Long)
Dim msg As String
MsgBox "data received"
Clientsock.GetData msg, vbString

ChatArea.Text = ChatArea.Text + " " & msg

End Sub

Private Sub CmdConnect_Click()

Clientsock.Close
ChatArea.Text = ChatArea.Text + " Refreshing Connection and connecting to server at " & SrvrIp.Text & " at port " & SrvrPort.Text & " "
Clientsock.Connect SrvrIp.Text, CInt(SrvrPort.Text)

End Sub

Private Sub CmdSend_Click()

If Clientsock.State = sckConnected Then
Clientsock.SendData MsgToSend.Text
MsgToSend.Text = ""
End If

End Sub

Private Sub MsgToSend_KeyPress(KeyAscii As Integer)

If KeyAscii = 13 Then
CmdSend_Click
End If

End Sub
 
 
   
 

 thatguypulkit - 7/2/2007 12:14:32 PM
   
 ' chat server code







Dim socks As Integer
Dim msg As String

Private Sub Command1_Click()
Dim i As Integer

SrvrLsn.Close
For i = 1 To socks - 1
If SrvrRcv(i).State = sckConnected Then
SrvrRcv(i).Close
Unload SrvrRcv(i)
End If
Next

SrvrRcv(0).Close

SrvrLog.Text = SrvrLog.Text + "Refreshing server and listening for new connections "

SrvrLsn.LocalPort = CInt(PortNo.Text)
SrvrLsn.Listen

End Sub


Private Sub SrvrLsn_ConnectionRequest(ByVal requestID As Long)

Dim i As Integer
UserCount.Text = CStr(socks + 1)
socks = socks + 1

Load SrvrRcv(socks)

SrvrRcv(socks).Accept requestID
SrvrRcv(socks).SendData CStr("Welcome to this chat room. Your Nick is ""User" & CStr(socks) & """")

SrvrLog.Text = SrvrLog.Text + "New user in room : User" & CStr(socks) & " "

msg = CStr("New user in room : User" & CStr(socks))

For i = 1 To (socks - 1)
SrvrRcv(i).SendData msg
Next

End Sub

Private Sub SrvrRcv_DataArrival(Index As Integer, ByVal bytesTotal As Long)


Dim i As Integer
SrvrRcv(Index).GetData msg, vbString

SrvrLog.Text = SrvrLog.Text + "Received message from User" & CStr(Index) & " : " & msg & " "

msg = "User" & CStr(Index) & " : " & msg

On Error Resume Next
For i = 1 To (socks)

If SrvrRcv(i).State = sckConnected Then
SrvrRcv(i).SendData CStr(msg)
'MsgBox "data sent to user" & i
Else
MsgBox "not connected to User" & CStr(i)
End If
Next

End Sub

Private Sub SrvrRcv_SendComplete(Index As Integer)
SrvrLog.Text = SrvrLog.Text + " Data sent to user" & Index & " : """ & msg & """"

End Sub
 
 
   
 

 thatguypulkit - 7/2/2007 1:10:04 PM
   
 please anyone who can help me with this... I'd be really grateful. I really need this problem solved... I'd be checking here too... but if you could please e-mail me at thatguypulkit@gmail.com It'd be a real help for me
 
 
   
 

 cyris69 - 7/15/2007 11:33:21 PM
   
 o work? I use my IP from http://myip.dk/ and give that to my friends

Oh, there is a problem with

For n = 1To SocketCounter
IfNot n = Index Then 'we don't want to send the msg back to the sender
If sock1(n).State = sckConnected Then 'if socket is connected
sock1(n).SendData "Client" & Index & " : " & dat
End If
End If
Next

It send msg to n(1) and n(last client) but none in the middle I'm going to try and recode that part.
 
 
   
 

 cyris69 - 7/15/2007 11:34:57 PM
   
 Sorry, cut off the top of my post
I can get this to work just fine Over LAN, I haven't messed with the socket code, I just changed around so each client can use he localhostname instead of client1,2,3,etc... it works over LAN but that cant connect via intranet
 
 
   
 

 VirusFree - 7/20/2007 10:30:08 AM
   
 [quote:2d081066b8="cyris69"]....[/quote:2d081066b8]

Well , lan and internet are not that different.

if you set the IP's correctly and the host is not blocked
(by firewalls or routers ) then it should connect fine
 
 
   
 

 MrMakealotofsmoke - 7/29/2007 3:52:20 AM
   
 Hey,
how would you make it so the users can set there name
 
 
   
 

 VirusFree - 7/29/2007 12:46:50 PM
   
 well you could make it so when the client connects , it send the desired nickname or other information and wait for the server to respond ok before
continuing with the chat

from the server site you could make it so the server will accept the information when a new client connects. it will validate them and send an ok
response back to client. the information could be story in an array.
 
 
   
 

 MrMakealotofsmoke - 7/30/2007 12:03:42 PM
   
 Ok, but ive only had VB for 2 days now, so im not good at it, and i got no idea what im doing.

can you please show me how to make it so the user can set there name.

and a good idea would be to add in someway of showing all the clients that a user has entered and disconnected from the room.
 
 
   
 
 
 
 
Post Comment
You need to be a registered user to post a comment
 


Your Comment :

Your post may only
contain the [url],[img]
[quote] tags and smiles.

Syntax :
[url]address[/url]
[url=address]anchor[/url]
[img]address[/img]
[quote="nick"]text[/quote]

You are NOT logged in. You can Login or Register to phoenixbit.com


 
 

 
 


Tutorial Top Sites - The Best Free Tutorial Sites!



Tags : software, computer security , software developers , software programming , freeware programs , online games
.
 Copyright © 2007 PhoenixBit. All rights reserved
.