| | | 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 |
| 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/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: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]
| |
|
|
| | | | |

|