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?
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
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
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
Last edited by CodeBlock; May 18th, 2005 at 09:05 AM.
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
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.
' 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 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)
Just to clear that up incase anyone takes anythign from this post.
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 . (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:
HTML Code:
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)
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
hi Hack,
i am doing problem this winsock. please enlighten me..
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.
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
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.
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]
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
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.
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.
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.
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?
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)
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)
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?
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:
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
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.
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: