# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  [Guide] Winsock - Chat Application

## Pino

Ok Ladies gents, and frogs, i have edited the guide slightly and included the source code now, I hope people find this usefull  :Smilie: 

 I have included it in the format of a word document with the source code all zipped up together,

 PINO-

----------


## chemicalNova

> _Originally posted by Pino_ 
> *
> Maybe a mod could make this a sticky*


Or you could post it in the CodeBank part of the forums..

Phreak

----------


## thegreatone

Bloody Ace, cheers mate that cleared up alot of my problems with winsock.

And made my latest project much easier to do  :Smilie:

----------


## Pino

> Bloody Ace, cheers mate that cleared up alot of my problems with winsock.
> 
> And made my latest project much easier to do


I'm so glad it helped  :Smilie: 

Comments like that make me want to write more guides  :Wink: 

Thanks  :Smilie:

----------


## Shadows

one word, fanastic. ty for sharing this, I got a warm buzz when I compile it and tested it  :Smilie:  .

one question tho about the server, I was thinking bout similar where the server is actually on a website n friends connect to the server.  An alternatively rather then someone having to have the server up n running where as it runs on a website's host.  Possible features would include voice communicating etc basically a neat chat room similar to teamspeak if you have used it.  Would this be hard?

----------


## Pino

> one word, fanastic. ty for sharing this, I got a warm buzz when I compile it and tested it  .
> 
> one question tho about the server, I was thinking bout similar where the server is actually on a website n friends connect to the server.  An alternatively rather then someone having to have the server up n running where as it runs on a website's host.  Possible features would include voice communicating etc basically a neat chat room similar to teamspeak if you have used it.  Would this be hard?


Thanks for the comments, you cant host the server on a website, because they usually dont let you host .exe files and if they do its very expensive  :Frown: 

Pino

----------


## Shadows

ye I know, I was thinking about the server being programming in php or java and the client made in vb6.  I'm still learning but from what I've heard, php has its own socket use for communicating with external programs or something on those lines.  Basically winsock communicating with the alternative for php

----------


## CodeBlock

Sorry Pino,

It just destroys one small point. Your's is just a Peer to Peer Chat application, Meaning: One Server for One Client. So you have a PeerServer which accepts connection for one client and a PeerClient which can connect only to one server. A Server, in complete, accepts more than one request from the client side.

To achieve this u need an Array of Winsock.
So, this code:


VB Code:
Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
    Winsock.Close 'this resets our socket ready to accept the incoming connection
    Winsock.Accept requestID 'accept the connection!
End Sub

becomes


VB Code:
' Place a new Winsock array exclusively for Clients - wskClients(0) is the default
Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
     newClient = wskClients.UBound + 1
    Load wskClients(newClient)
     wskClients(newClient).Accept requestID 'accept the connection with our new Winsock
   ' So the Server continues to listen for more clients
End Sub

Anyway, Very Good code for beginners.

Regards

HTH
Neo

*Edit:* Fixed vbcode tags - Hack

----------


## Pino

What i tend to find is hen learning to use winsock beginners find array very confusing and hence this aplication isnt Mulit-User chat but a very simple 2 person chat which demonstrates how to start a server connect and send data the fundementals of winsock, then if they wish to take it any further they can start to look at arrays but as I say this example is designed to be kept simple, i dont want to over complecate and confuse people  :Smilie: 


Anyhows i appriciate your comments and if you wish why not write up a  guide demonstarating how to sue control arrays with winsock. I am in the middle of writing up the Network FAQ so if the guide is good I can link to it.

 :Smilie:

----------


## Pino

Also just to pick up on the code you posted,




> becomes
> 
> VB Code:
> ' Place a new Winsock array exclusively for Clients - wskClients(0) is the default
> Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
>  newClient = wskClients.Count + 1
> Load wskClients(newClient)
>  wskClients(newClient).Accept requestID 'accept the connection with our new Winsock
> ' So the Server continues to listen for more clients
> End Sub


Faior enough but what happens if we have lots of clients connecting and then some leave?Over time you will have a large amount of un-used sockets which are just wasting server memory  :Frown:  which isnt good if we are developing a serve rof some kind.

also this line


VB Code:
Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)

if we are using an array should be....


VB Code:
Private Sub Winsock_ConnectionRequest([B]index as integer,[/B]ByVal requestID As Long)

 :Smilie:  Just to clear that up incase anyone takes anythign from this post.

Pino

----------


## CodeBlock

Hey Pino,

Why dont you read my previous post properly! In a hurry i have forgot to close the [ vbcode ] properly. So, it ended up with a code line that made you not to notice the first line. I have specified you to create a new Winsock and name it as wskClients exclusively for Clients, and NOT to make the existing Winsock as an array. That way u need to change a lot of code, such as, to replace with Winsock(0) with Winsock everywhere.

So, y do you need this:

VB Code:
Private Sub Winsock_ConnectionRequest([color=red]Index As Integer,[/color] ByVal requestID As Long)

I closely look at codes before posting, So dont worry  :Wink:  . (Please look at my code carefully) My Code is correct:


VB Code:
Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)

Because, it is only wskClients an Array and not the listening Winsock object.

Also, regarding the code:
I just gave a starting idea. If you want to continue, i will do it. It is obvious that u have to unload objects when they get closed, isnt it?


VB Code:
Private Sub wskClients_Error(Index As Integer, ByVal Number As Integer, _
Description As String, ByVal Scode As Long, ByVal Source As String, ByVal _
HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
       Call wskClients_Close(Index)
 End Sub
 ' Clean up code
Private Sub wskClients_Close(Index As Integer)
    wskClients(Index).Close
    Unload wskClients(Index)
End Sub

But there is one small modification instead of using the .Count, its better to use the .UBound variable

So the Index variable keeps increasing. But the objects get unloaded. At point of time, when all clients quit all winsocks unload. I have a graph on Winsocks Clients Connection/DisConnection Time Line:




```
Slots Marked with x are loaded wskClients

 No.  Clients

      1  2  3  4  5  6  7  8  9  10  .Count .UBound+1 <-- New Empty WinSock
    _____________________________________________________
 1  | x					1       2      New Client Connects
 2  | x  x				2       3      New Client Connects
 3  | x  x  x				3       4      New Client Connects
 4  | x     x                           2       4      Client 2 DisConnects
 5  | x     x  x                        3       5      New Client Connects
 6  | x     x  x  x                     4       6      New Client Connects
 7  | x     x     x                     3       7      Client 4 Disconnects 
 8  | x     x                           2       4      Client 5 Disconnects
 9  | x     x  x                        3       5      New Client Connects
 10 | x        x                        2       5      Client 3 Disconnects
 11 | x        x  x                     3       6      New Client Connects
 12 |          x  x                     2       6      Client 1 Disconnects
 13 |             x                     1       6      Client 4 Disconnects
 14 |                                   0       1      Client 5 Disconnects
 15 | x                                 1       2      Cycles again in some combination
 16 |___________________________________________   
```



Hehe.. just a research i made.. to explain...

This means (.UBound + 1) always refers to a New Client

So the code becomes:

VB Code:
' Place a new Winsock array exclusively for Clients - wskClients(0) is the default
Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
     newClient = wskClients.UBound + 1 ' instead of .Count + 1
    Load wskClients(newClient)
     wskClients(newClient).Accept requestID 'accept the connection with our new Winsock
   ' So the Server continues to listen for more clients
End Sub
  Private Sub wskClients_Error(Index As Integer, ByVal Number As Integer, _
Description As String, ByVal Scode As Long, ByVal Source As String, ByVal _
HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
       Call wskClients_Close(Index)
 End Sub
 ' Clean up code
Private Sub wskClients_Close(Index As Integer)
    wskClients(Index).Close
    Unload wskClients(Index)
End Sub

Any Comments?

HTH
Neo

----------


## Pino

Yes please create a new thread if you wish to continue this one  :Smilie:  i'd prefer to keep this one simple as no to confuse the target programmer.

And if i read your code in-correctly i appoligise.

 :Smilie:

----------


## ocw

hi..
 i am stuck with the broadcast stuff...how???
this is my code here..--->


VB Code:
[COLOR=Green]Option Explicit
 Dim buffer() As Byte
Dim lBytes As Long
Dim temp As String
Dim index As Long
Private Sub cmdBrowse_Click()
  dlg.ShowOpen
  txtFile = dlg.FileName
End Sub
 Private Sub cmdSend_Click()
Dim index As Long
  cmdSend.Enabled = False
  lBytes = 0
  ReDim buffer(FileLen(dlg.FileName) - 1)
  Open dlg.FileName For Binary As 1
  Get #1, 1, buffer
  Close #1
  Load wsTCP(1)
     wsTCP(1).RemoteHost = "255.255.255.255"
  wsTCP(1).RemotePort = 1111
  wsTCP(1).Connect
  lblStatus = "Connecting..."
End Sub
 Private Sub wsTCP_Close(index As Integer)
  lblStatus = "Connection closed"
  Unload wsTCP(1)
End Sub
 Private Sub wsTCP_Connect(index As Integer)
   Dim i As Long
   ' Loop through the control array of clients and send the data on each one.
   For i = 1 To wsTCP.UBound
           wsTCP(index).SendData dlg.FileTitle & vbCrLf
   Next i
  
End Sub
 Private Sub wsTCP_DataArrival(index As Integer, ByVal bytesTotal As Long)
  wsTCP(index).GetData temp
  If InStr(temp, vbCrLf) <> 0 Then temp = Left(temp, InStr(temp, vbCrLf) - 1)
  If temp = "OK" Then
    wsTCP(index).SendData buffer
  Else
    lblStatus = "Something wrong"
    Unload wsTCP(index)
    cmdSend.Enabled = True
  End If
End Sub
 Private Sub wsTCP_SendComplete(index As Integer)
  If temp = "OK" Then
    lblStatus = "Send complete"
    temp = ""
    Unload wsTCP(1)
    cmdSend.Enabled = True
  End If
End Sub
 Private Sub wsTCP_SendProgress(index As Integer, ByVal bytesSent As Long, ByVal bytesRemaining As Long)
  If temp = "OK" Then
    lBytes = lBytes + bytesSent
    lblStatus = lBytes & " out of " & UBound(buffer) & " bytes sent"
  End If
End Sub[/COLOR]

need help urgently...
really appreciated a lot..
thanks..

ocw

----------


## ocw

> Sorry Pino,
> 
> It just destroys one small point. Your's is just a Peer to Peer Chat application, Meaning: One Server for One Client. So you have a PeerServer which accepts connection for one client and a PeerClient which can connect only to one server. A Server, in complete, accepts more than one request from the client side.
> 
> To achieve this u need an Array of Winsock.
> So, this code:
> 
> 
> VB Code:
> ...



hi Hack,

i am doing problem this winsock. please enlighten me..

newClient = wskClients.UBound + 1
    Load wskClients(newClient)

    wskClients(newClient).Accept requestID 'accept the connection with our new Winsock

what is the "WskClient" doing in the prog?

???
ocw

----------


## Pino

WskClients is the name of the winsock control array, 

Its just renamed from Winsock1.

The code above finds out which number is one above the UBound array and then creates a new socket on that number. 

Is that what you mean?

Guys I must stress the main intention of this guide was to provide a simple beginning the winsock IE one client one server its going a bit beyond that now.

----------


## ocw

hi guys.. 

i have tried numerous times on this Winsock based on the guide lines and points mentioned in this forum. apart from so many connection_request methods discussed, i find it very interesting. HOwever, i have a question on how to send the data? if i have 10 listener waiting for my data, how can i broadcast to them? if i open two listener on different station within the network listening on the same port(port 1111), the error will pop out saying something like " adddress been used" and Control array element '2' doesn't exist. i really need yours guidances..

[vb code]

*sending method*

Private Sub cmdSend_Click()

Dim Index As Long
Dim i As Integer
  cmdSend.Enabled = False
  lBytes = 0
  ReDim buffer(FileLen(dlg.FileName) - 1)
  Open dlg.FileName For Binary As 1
  Get #1, 1, buffer
  Close #1

 For i = 1 To wsClient.UBound + 1
  Load wsClient(i)   'wsClient as my WinSock TCP protocol
  wsClient(i).RemoteHost = "192.168.122.255"  'my broadcast address
  wsClient(i).RemotePort = 1111
  wsClient(i).Connect
  lblStatus = "Connecting..."

  Next i

[/vb code]

should i loop the wsClient like the way it had mentioned in this forum??? i have a similar connection_request methodas in the forum.


[vb code]
Private Sub wsClient_Connect(Index As Integer)
   Dim i As Long

   ' Loop through the control array of clients and send the data on each one.
     For i = 1 To wsClient.UBound + 1
           wsClient(i).SendData dlg.FileTitle & vbCrLf
   Next i
  End Sub

[/vb code]

Greatly appreciated...
ocw

----------


## Pino

To send a message to all clients connected do this,


VB Code:
for i = 0 to winsock.ubound - 1
        if winsock(i).state = sckconnected then
                wisnock(i).senddata "Data"
        end if
   doevents
next i

thats all you need to do, no need to open up any more connectiosn etc.

----------


## Pino

this amkes no sence either...

VB Code:
For i = 1 To wsClient.UBound + 1
Load wsClient(i) 'wsClient as my WinSock TCP protocol
wsClient(i).RemoteHost = "192.168.122.255" 'my broadcast address
wsClient(i).RemotePort = 1111
wsClient(i).Connect
lblStatus = "Connecting..."
 Next i

why are you looping to connect?

----------


## Pino

post me your client and sever applications.

pino

----------


## ocw

> To send a message to all clients connected do this,
> 
> 
> VB Code:
> for i = 0 to winsock.ubound - 1
>         if winsock(i).state = sckconnected then
>                 wisnock(i).senddata "Data"
>         end if
>    doevents
> ...


hihi..

what about the code below?
[vb code]
 Load wsClient(1)
  wsClient(1).RemoteHost = "192.168.122.222" 'not a broadcast address (should i place a broadcast add to 192.168.122.255?)
  wsClient(1).RemotePort = 1111
  wsClient(1).Connect
  lblStatus = "Connecting..."[/vb code]

should i made any changes to it?

real thanks..

??
ocw

----------


## Pino

What is that code supposed to do? Looks very strange.....

----------


## ocw

> What is that code supposed to do? Looks very strange.....


hihi..

thanks Pino, this is my application. the objective of my application should be able to broadcast the all stations within the network.

real thanks..

??
ocw

----------


## ocw

> this amkes no sence either...
> 
> VB Code:
> For i = 1 To wsClient.UBound + 1
> Load wsClient(i) 'wsClient as my WinSock TCP protocol
> wsClient(i).RemoteHost = "192.168.122.255" 'my broadcast address
> wsClient(i).RemotePort = 1111
> wsClient(i).Connect
> lblStatus = "Connecting..."
> ...


sorry for the weird code given. i just want to try if i could send the data to all the stations within the network. i am not sure on winsock. 

sigh...
ocw

----------


## Pino

what does the app do? I can see deleting files, raises alarm bells....

----------


## Pino

Ok, 

Wisnock(0) allwasy listens its the only one listening. from here it loads a new socket.

cahnge these parts,


VB Code:
Private Sub ws_sev_ConnectionRequest(index As Integer, ByVal requestID As Long)
  Dim i As Long
  
    i = wskClients.UBound + 1
    Load ws_sev(newClient)
     ws_sev(newClient).Accept requestID
End Sub

and change this also


VB Code:
Private Sub cmdRun_Click()
  If cmdRun.Caption = "Run" Then
    cmdRun.Caption = "Stop"
    
    ws_sev(0).LocalPort = 1111
    ws_sev(0).Listen
    
  Else
    ws_sev(0).Close
    cmdRun.Caption = "Run"
  End If
End Sub

----------


## ocw

> Ok, 
> 
> Wisnock(0) allwasy listens its the only one listening. from here it loads a new socket.
> 
> cahnge these parts,
> 
> 
> VB Code:
> Private Sub ws_sev_ConnectionRequest(index As Integer, ByVal requestID As Long)
> ...


hihi..

i have change the code. now the error throws "connection close" at the statue label.

ocw

----------


## Pino

i didnt look through the rest of the code, i havent had chance, and i'm not runnign the program, until you tell me what it does, I cant help you any further  :Frown: 

Pino

----------


## ocw

> what does the app do? I can see deleting files, raises alarm bells....


hihi..

the application will override the file if there are duplicate file name. the main objective to this applicaition is to send the file to all stations within the network (broadcasting)...

now, the application only able to send to the one port or one station.


thanks Pino.

Best regards
ocw

----------


## Pino

I cant make head nor tail of the code, the server is supposed to send the file out right? 

I think you best go back to basics, cut all the disabling commands etc, and just stay winsock, then really focus on what is supposed to go on.

Pino

----------


## ocw

> I cant make head nor tail of the code, the server is supposed to send the file out right? 
> 
> I think you best go back to basics, cut all the disabling commands etc, and just stay winsock, then really focus on what is supposed to go on.
> 
> Pino


sorry fro the messy codes, the server is suppose to listen for the data, while the client is suppose to send the data. by using the localhost ip, i am able to send to my station destop. but when i change the RemoteIP to the "192.168.122.255" the broadcast add, it fails to broadcast the data, even to my station.

thus, i have wondering is my connection_request and the sending of data is correct.

thanks pal
ocw

----------


## CVMichael

First of all, you can't broadcast with TCP only UDP.
And with UDP, the broadcast IP is 255.255.255.255 (and it works only for local network)

The example Pino gave to broadcast, does not really broadcast, it's simply sending a message to everyone who is connected.
For example if you have 10 connections, and you want to send the same message to all 10, then you send to the first one, then the second, and so on.
That means that if you have a message that is 100 bytes (lets say), you will end up sending 100 * 10 = 1000 bytes. Wich is NOT broadcast.

Broadcast means you send 10 bytes ONCE and everyone gets the message.

Also, what you want is multicast, not broadcast, you want a select # of people to get the message, not EVERYONE ?

So, if you REALLY want to broadcast you have to switch to UDP protocol. Also don't forget that even that, works only for local network.

----------


## BladeZ

im having some big problms with my code can someone tell me why when the client sends something it doesnt appear in the server screen and am i doing the multiple connections thing right?


*Server* 

VB Code:
Dim msgarrived As String
Dim i As Integer
 Private Sub cmdsend_Click()
For i = 0 To server.ubound - 1
        If server(i).State = sckConnected Then
server(i).SendData txtnickname.Text & ": " & txtmsg.Text
txtchat.Text = txtnickname.Text & ": " & txtmsg.Text & vbNewLine
txtmsg.Text = ""
        End If
   DoEvents
Next i
End Sub
  Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
     newClient = server.ubound + 1
    Load server(newClient)
     server(newClient).Accept requestID
End Sub
 Private Sub server_DataArrival(Index As Integer, ByVal bytesTotal As Long)
server(i).GetData msgarrived
txtchat.Text = msgarrived & vbNewLine
End Sub
 Private Sub server_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
Call server_Close(Index)
End Sub
 Private Sub server_Close(Index As Integer)
    server(Index).Close
    Unload server(Index)
End Sub


*Client* 

VB Code:
Option Explicit
Dim msgarrived As String
Dim i As Integer
  Private Sub cmdconnect_Click()
client(i).Connect txtip.Text, txtportnum.Text
MsgBox "Connected To " & txtip.Text
End Sub
 Private Sub cmdsend_Click()
For i = 0 To client.ubound - 1
        If client(i).State = sckConnected Then
client(i).SendData txtnickname.Text & ": " & txtmsg.Text
txtchat.Text = txtnickname.Text & ": " & txtmsg.Text & vbNewLine
txtmsg.Text = ""
        End If
   DoEvents
Next i
 End Sub
 Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
     newClient = server.ubound + 1
    Load client(newClient)
     client(newClient).Accept requestID
End Sub
 Private Sub client_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
Call client_Close(Index)
End Sub
 Private Sub client_Close(Index As Integer)
    client(Index).Close
End Sub

----------


## Pino

change, 


VB Code:
Private Sub server_DataArrival(Index As Integer, ByVal bytesTotal As Long)
server(i).GetData msgarrived
txtchat.Text = msgarrived & vbNewLine
End Sub

on the server to say


VB Code:
Private Sub server_DataArrival(Index As Integer, ByVal bytesTotal As Long)
server(index).GetData msgarrived
txtchat.Text = msgarrived & vbNewLine
End Sub

that will work!

----------


## CodeBlock

A Good Muliti Connection Chat App should have some strict rules:

*Server Rules:*
1. Must Run only *ONCE* and listen at a specific port
2. Must Accept connections from clients by transfering the incoming connection to a new Socket, thus keeping the Listening socket available for more clients to connect.
3. Cannot have a User-Interface (its not a Client, please remember) to interact with a User (Except for Admin Messages and advanced stuff)
4. may try to redirect most messages for simplicity
5. Should follow a Protocol common to both the client and the server. Protocol may be simple from user-defined to complex such as IRC, IRCX ... etc

*Client Rules:*

1. Should Connect to a Server using just one Winsock - NO ARRAYS
2. Any new client starting, should start on its own new Application (new process)
4. Can have User Interface for Client Interaction
3. Follow the same protocol as supported by the Server


See whether u follow the above rules

For a person to chat with another person, 3 apps will run at the least.

One will be the server and the other two will be the two person's client app.

So if Person 1 wants to send message to Person 2, the client1 first contacts the server the server then send the message to client 2.

Thus, the server is like a mediator.

Due to these reasons, u have to first remove text boxes from ur server app. The Server app cannot act like a client, hehe, Can it?   :Sick:   :Smilie:  

And Regarding Protocols, its better to send your messages with some extra commands along with ur message. And dont forget to seperate your message with a delimiter. 99% of Chat Clients use vbCrLf as the message seperator.

So your code can look like this after some modifications:

*Server:*

VB Code:
Dim msgarrived As String
Dim i As Integer
 'Private Sub cmdsend_Click()
'For i = 0 To server.ubound - 1
'        If server(i).State = sckConnected Then
'            server(i).SendData txtnickname.Text & ": " & txtmsg.Text
'            txtchat.Text = txtnickname.Text & ": " & txtmsg.Text & vbNewLine
'            txtmsg.Text = ""
'        End If
'   DoEvents
'Next i
'End Sub
 Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
     newClient = server.ubound + 1
    Load server(newClient)
     server(newClient).Accept requestID
End Sub
 Private Sub server_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim Data As String
server(Index).GetData Data, vbString
    
    ' If we have any data remaining from the previous DataArrival Call
    Data = Messages(Index) & Data
     Dim Messages() As String
    
    Messages = Split(Data, vbCrLf)
    For i = LBound(Messages) To UBound(Messages) - 1
        ParseMessage Messages(i)
    Next i
    ' We are adding the last message as buffer to prevent data loss
    server(Index).Tag = Messages(i)
End Sub
 Private Sub server_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
Call server_Close(Index)
End Sub
 Private Sub server_Close(Index As Integer)
    server(Index).Close
    Unload server(Index)
End Sub
  Sub ParseMessage(Message As String)
Dim CMDs() As String
Dim RealMessage As String
Dim i As Long
     ' Message can be like
    ' MSG MyNickName :hi all
    ' PM MyNickName CodeBlock :hi mate ;)
     ' Seperate Commands from Real Message, Colon ":" is our seperator
    i = InStr(1, Message, ":")
    RealMessage = Mid$(Message, i + 1)
    
    ' get the commands such as MSG or PM CodeBlock ... etc
    Message = Left$(Message, i - 1)
    CMDs = Split(Message, " ")
    
    Select Case CMDs(0)
        Case "MSG":
            ' Cmds(1) has the nickname of the sender
            ' This command means message to all
            For i = 0 To UBound(server)
                ' MSG SenderNick:Real Message
                server(i).SendData "MSG " & CMDs(1) & ":" & RealMessage
            Next i
        Case "PM":
            ' Cmds(1) has the nickname of the receiver
            '...
    End Select
End Sub

----------


## Pino

Please, you have to look at a users ability and where they are in, learning or expert. he/She is clearly learning so this stuff is not nessercery. And a server can have an interface/control pannel. 

As i have mentioned before please create anew thread if you wish to make an advanced guide. Again I will quote myself. Before i have to have this thread split.




> Guys I must stress the main intention of this guide was to provide a simple beginning the winsock IE one client one server its going a bit beyond that now.

----------


## moeur

I never liked leaving holes in my array of servers so I use this simple function to load the next server.

VB Code:
Function LoadNextServer(wsServer) As Long
Dim wsck
Dim i As Long
    i = 0
    For Each wsck In wsServer
        If wsck.Index > i Then
            LoadNextServer = i
            Load wsServer(i)
            Exit Function
        Else
            i = i + 1
        End If
    Next
    LoadNextServer = i
    Load wsServer(i)
End Function

Then you would call it like this
VB Code:
Private Sub Server_ConnectionRequest(Index As Integer, ByVal requestID As Long)
Dim newClient As Long
    If Index = 0 Then
    'this is the listening server
    'load a new control to talk to this client
        newClient = LoadNextServer(Server)
        Server(newClient).Accept requestID
        Server(newClient).SendData "Hello: you are connected"
    End If
End Sub

Pino, sorry if you think this is too advanced, but I think it is basic.

----------


## guyjasper

i need clarification on this one. in the winsock array, say for example i loaded 5 winsocks because there are 5 clients that connected, if the starting index for my winsock array is 0, then winsock.ubound would be 4,right? and when another client would connect, i would load winsock(5) to accept that connection, and calling winsock.ubound would give me 5, is this right? 

and then for example winsock(1) is closed and unloaded, only 5 winsocks would be left because winsock(1) is removed but winsock.ubound would still be 5, right?  because the array index would not rollback even if you unload an item that is part of the array. 

so i guess in a multi client-server application, it is not safe to iterate thru all clients using something like:

VB Code:
for i=0 to ubound(sckClients)
    sckClients(i).senddata "blah...blah...."
next i

it is better i think to use a for each loop.

----------


## Pino

Ok, here is how it works

Winsock(0) allways listens, when it gets a connection request it passes it on to the next avalible winsock,

Winsock(1), Winsock (2) etc

as for the loop here is how to senddata to all connected clients,


VB Code:
For i = winsock.ubound - 1
        if winsock(i).state = sckconnected then
               winsock(i).senddata "hello"
         end if
   doevents
next i

Hope that helps, if you have any furthur questions could you make a new post in the network section? 

Thanks

Pino

----------


## moeur

> VB Code:
> For i = winsock.ubound - 1
>         if winsock(i).state = sckconnected then
>                winsock(i).senddata "hello"
>          end if
>    doevents
> next i


I think Pino was half asleep when he wrote this.  For one thing it won't work if a control has been unloaded.

Instead I would do this
VB Code:
Dim wsk As Winsock
    For Each wsk In Winsock
        If wsk.State = sckConnected Then _
            wsk.SendData "Hello"
    Next

----------


## Pino

Nice polite person you are  :Roll Eyes (Sarcastic): 

Can I ask how a sockect would be unloaded? seriosuly, I have never had a problem.

----------


## moeur

When a client disconnects I normally unload the Winsock control that is associated with that client
VB Code:
Private Sub Winsock_Close(Index As Integer)
    Unload Winsock(Index)
End Sub

----------


## CVMichael

Isn't it better if you leave it as it is, but just close the connection ? That way you can use it later on, for a new connection... (that's what I always do)
Also... I think it's weird to have a gap in the control array...

----------


## moeur

> Also... I think it's weird to have a gap in the control array...


So do I, hence my previous bit of code.
Poor Pino, we're ruining his nice thread.

----------


## CVMichael

I mean like this:

This code is from the server I made for work, wich we use for more than a year now...

VB Code:
Private Sub SckTCP_Close(Index As Integer)
    CClients = CClients - 1
    SckTCP(Index).Close
    ClearUser Index
    
    If Index = 0 Then
        ConnectAllSockets
    End If
End Sub
 Private Sub SckTCP_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim K As Integer, SHA As New clsSHA256, StrToSend As String
    
    For K = 1 To SckTCP.UBound
        If SckTCP(K).State = sckClosed Then Exit For
    Next K
    
    If K = SckTCP.UBound + 1 Then
        Load SckTCP(SckTCP.UBound + 1)
        Load tmrSendData(SckTCP.UBound)
        
        ReDim Preserve Clients(SckTCP.UBound)
        
        K = SckTCP.UBound
    End If
    
    Randomize
    Clients(K).State = 0
    Clients(K).CLogIn.RndINIT = UCase(SHA.SHA256(CStr((2 ^ 30) * Rnd)))
    
    SckTCP(K).Accept requestID
    
    StrToSend = "RndINIT|" & Clients(K).CLogIn.RndINIT
    SckTCP(K).SendData Len(StrToSend) & ":" & StrToSend
    
    CClients = CClients + 1
End Sub

----------


## mysticmerlin07

> Ok Ladies gents, and frogs, i have edited the guide slightly and included the source code now, I hope people find this usefull 
> 
>  I have included it in the format of a word document with the source code all zipped up together,
> 
>  PINO-



This is a very good tutorial but you forgot to include some stuff (which the most BEGINNER programmers wouldnt know how to do)

in the parts where you say stuff like

"ok so now your server is listening we must handle connection requests, this is when the client trys to connect to us!



Private Sub Winsock_ConnectionRequest(byVal RequestID as long)"

you didnt include the part that tells HOW to get the above statement (the sub_winsock_connectionrequest) event...so that may be a tad bit confusing (of course I kno how to get it cuz this is my 2nd year of programming)...you also didnt mention that you have to double click the form and select the LOAD property to enter the first bit of code you give

sorry for the negative feedback...just think of it as constructive criticism  :Smilie: 

thanks for the tutorial...hopefully i wont have any questions but if i do i will let you know...and maybe we can write another tutorial together  :Smilie:

----------


## Pino

Thanks for your comments,

I think if somone is beginning to learn winsock then they should know a decent level of programming, and stuff like getting the correct subs well i'd assume they would know that.

Thanks for the feedback though, either way the guide has helped several people get to grips wihth winsock thats all it was here for not supposed to be a full explination  :Smilie:

----------


## mysticmerlin07

your welcome for the comments, again I am sorry they sounded so negative....

i attempted to use it to learn winsock...but its just wayyy over my head...

normally when you learn a new command u learn the generic use of it correct? such as the command button....when I learned it all we first learned to do was make a pic visible..so thats simple....winsock is just....CONFUSING!

thanks for taking the time out to write the guide regardless...and i hope you have fun in the future with whatever helpful projects you make work on  :Smilie:

----------


## Pino

Well in all honesty this is the simplest format of how winsock works, if this above you I feel you are not ready. Also this is old now move to .NET :-D

----------


## Raghibkhesal

Thanks
Because this codes helped me very much. 


Raghib Khesal
KGCS
raghib.netfirms.com

----------


## brian.sykes

Alright i dont know if this will help anyone but this connectionrequest code is from my chat server which can handle as many winsock controls that vb can open.  If this has been posted or something similar to it i apologize but it works friggin great seeing as it checks for any unused sockets that are still open before making new ones so it recycles the old ones and keeps reusing them saves huge on memory


VB Code:
Private Sub sckData_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim t1, t2
    Dim i As Long, num As Long
    If IsServerBanned(sckData(Index).RemoteHostIP) = "True" Then Exit Sub
CheckSockets:
    For i = 1 To sckData.UBound
        If sckData(i).State = 0 Or sckData(0).State = 8 Then
            sckData(i).Close
            sckData(i).Tag = ""
            sckData(i).Accept requestID
            WriteToLog sckData(i).RemoteHostIP & " is attempting to connect", RGB(0, 0, 0)
            sckData(i).SendData "gi" & Chr(10)
            Exit Sub
        End If
        DoEvents
    Next i
    DoEvents
    num = sckData.UBound + 1
    Load sckData(num)
    sckData(num).Accept requestID
    WriteToLog sckData(i).RemoteHostIP & " is attempting to connect", RGB(0, 0, 0)
    sckData(num).SendData "gi" & Chr(10)
End Sub

Just ignore the senddata stuff chat protocols and stuff

----------


## CVMichael

That's basically the same idea of the code I posted in post #44

----------


## mikepost

I'd like to thank y'all for making my life alot easier.  I've used code based on this thread for a couple of years for several meteorological servers where I work.  It works great!

Does anyone have any idea how to do this stuff in VB2005?  My research into this indicates you need about 10 times the amount of code to maybe achieve the same results.  :Confused:

----------


## Niko18

I dont have word, but i need the tut.  :Frown:

----------


## bITO123

Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)
newClient = wskClients.Count + 1
Load wskClients(newClient)
wskClients(newClient).Accept requestID 'accept the connection with our new Winsock
End Sub

Doesent work to me it say method member not found And sory i didtn place it in the VB code box becouse it sux and i dont know how to use it becouse im a idiot...

----------


## remya1000

instead of Local machine whether i can connect to Remote machine.

i just created a combobox and inside that i have "localhost" and remote machine eg:"a1".
if selected is localhost, it will connect. but if the selected item is a1(remote machine) it's not connecting.
this the code i'm using....

SEND
------
Private Sub frmSend_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        comboBoxIP.Items.Add("localhost")
        comboBoxIP.Items.Add("a1")
    End Sub

Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConnect.Click
        wsSend.Close()
        wsSend.Connect(comboBoxIP.Text, 1223)       End Sub

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        wsSend.SendData(txtSendWhat.Text)
    End Sub

RECEIVE
--------
Private Sub frmSend_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim frmReceive As New frmReceive
        frmReceive.Show()
        wsReceive.Close()
        wsReceive.LocalPort = 1223
        'wsReceive.RemotePort = 1223                   wsReceive.Listen()
    End Sub 

Private Sub wsReceive_ConnectionRequest(ByVal sender As Object, ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_ConnectionRequestEvent) Handles wsReceive.ConnectionRequest
        If wsReceive.CtlState <> MSWinsockLib.StateConstants.sckClosed Then
            wsReceive.Close()
        End If

        wsReceive.Accept(e.requestID)

        If wsReceive.CtlState = MSWinsockLib.StateConstants.sckConnected Then
            Call wsReceiveConnected()
        End If
    End Sub

 Private Sub wsReceive_DataArrival(ByVal sender As Object, ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles wsReceive.DataArrival
        Dim str As String
        wsReceive.GetData(str, vbString)
        txtMessageReceived.Text = str
 End Sub

if i need to connect to a remote machine, what is the change i need to do in this code. i'm not getting anyidea.... if you know how to do that please let me know .
thanks in advance and thanks for your post and link.. its very usefull for me...

----------


## paralyzedcitizen

I'm trying to do this at home but I cant find the winsock control? i even tried browsing for it and running a search but could not find it. I'm running Vista, is this why? how would i go about this project if so?

----------


## Pino

> I'm trying to do this at home but I cant find the winsock control? i even tried browsing for it and running a search but could not find it. I'm running Vista, is this why? how would i go about this project if so?


This is very old code Visual Baisc 6, what version are you using?

----------


## paralyzedcitizen

I'm using VB6. I know it's old and I should be using .net but my mate gave it to me and that's why i've learnt vb6. I have started to learn .net with 2005 but i prefer vb6 to be honest.

----------


## paralyzedcitizen

*Bump*

----------


## CVMichael

paralyzedcitizen, why don't you start a new thread where you ask for your problem instead of "hijacking" a year old thread ?

Make sure your thread title is about your problem, something like "Winsock on Vista"

----------


## paralyzedcitizen

> paralyzedcitizen, why don't you start a new thread where you ask for your problem instead of "hijacking" a year old thread ?


? 

My query is directly related to this thread, I'm trying to make the chat application from the first post. Surely this thread couldn't be more relavent? And if I created a new thread I would most likely just get linked back here.

----------


## ohailo

yay men....its not working if you try to connect it using other computer to other computer...but do nice..

----------

