Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problem with Winsock. I don't know how.... 1

Status
Not open for further replies.

ares666

Programmer
Jun 20, 2003
7
0
0
RO
I've designed an application for use as a chat system to ease the communication between friends at work, taking this opportunity to learn VB programming.

So here goes:
my application is designed as a client - server utility, ergo there are two parts: a client and a server.
I've included in each of the forms a winsock control, have set the localport on the server to be 666, and the remoteport on the client to be 666, I've set the server to listen and so far it works just fine. But only for ONE client. So, naturally, I was looking for a way to enable multiple connections to the same server, because that is what I want my application to be, a chat environment.
Ok, in order to allow multiple connections to the same server, I've set the index property of the server's winsock control to 0 (zero), and on the "incoming call", this socket loads another instance of itself, with another index, such as 1, and so on. Well, so far so good...
But THE PROBLEM really is that when I connect any second client, the text string send from the first client to the server does not show in the server's textbox, altough it should... here is what I did: I compiled and made .EXEs both out of the client only, and out of the client-server together. Code follows, so if anyone can think why do I have this problem, I would be in debt if I get any tips how to solve it, or work around it... Thank you, in advance, ARES.

Code
==========================================
- for the CLIENT:
==========================================
Private Sub Command1_Click()
If tcpClient.State = sckConnected Then
tcpClient.SendData Text3.Text & ":" & Text2.Text
Text1.Text = Text3.Text & ":" & Text2.Text & vbCrLf & Text1.Text & vbCrLf
Text2.Text = ""
Else:
MsgBox "There is no connection.", vbCritical + vbOKOnly, "Connect first"


End If
End Sub

Private Sub Command2_Click()
Frame3.Caption = "Nick: " & Text3.Text
nick = Text3.Text
End Sub

Private Sub Command3_Click()
If tcpClient.State <> sckClosed Then
MsgBox &quot;You're already connected&quot;, vbOKOnly + vbCritical, &quot;Already connected&quot;
Else:
tcpClient.RemoteHost = Text4.Text
tcpClient.RemotePort = 666
tcpClient.Connect
client.Caption = &quot;Jn Chat Client. Status: &quot; & tcpClient.State
client.Refresh
End If
End Sub



Private Sub Form_Load()
' The name of the Winsock control is tcpClient.
' Note: to specify a remote host, you can use
' either the IP address (ex: &quot;121.111.1.1&quot;) or
' the computer's &quot;friendly&quot; name, as shown here.
nick = tcpClient.LocalHostName
client.Caption = &quot;Jn Chat Client. Status: &quot; & tcpClient.State
End Sub
Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
tcpClient.GetData strData
Text1.Text = strData & vbCrLf & Text1.Text
End Sub
===========================================
end code for the client app.
===========================================

Code
====================================
-for the SERVER
====================================
Private nick As String
Private intMax As Long


Private Sub Command1_Click()
If tcpServer(intMax).State <> sckConnected Then
MsgBox &quot;Nu este nici un client conectat. Aveti nevoie de ajutor profesional, caci ati inceput sa vorbiti singur.&quot;, vbCritical + vbOKOnly, &quot;Awaiting clients&quot;
Else:
tcpServer(intMax).SendData nick & &quot;:&quot; & Text2.Text
Text1.Text = Text3.Text & &quot;:&quot; & Text2.Text & vbCrLf & Text1.Text
Text2.Text = &quot;&quot;
End If
End Sub

Private Sub Command2_Click()
Frame3.Caption = &quot;Nick: &quot; & Text3.Text
nick = Text3.Text
End Sub

Private Sub Command3_Click()
Text1.Text = List1.Text & vbCrLf & Text1.Text
End Sub

Private Sub Form_Load()
intMax = 0
tcpServer(0).LocalPort = 666
tcpServer(0).Listen
client.Show
Frame3.Caption = &quot;Nick: &quot; & tcpServer(0).LocalHostName
Text3.Text = &quot;SERVER&quot;
nick = &quot;SERVER&quot;
End Sub

Private Sub tcpServer_ConnectionRequest _
(index As Integer, ByVal requestID As Long)
If index = 0 Then
intMax = intMax + 1
Load tcpServer(intMax)
tcpServer(intMax).LocalPort = 666
tcpServer(intMax).Accept requestID
'Load txtData(intMax)
End If
'If tcpServer.State <> sckClosed Then tcpServer.Close
'tcpServer.Accept requestID
List1.AddItem tcpServer(intMax).RemoteHost
End Sub

Private Sub tcpServer_DataArrival(index As Integer, ByVal bytesTotal As Long)
Dim strData As String
tcpServer(intMax).GetData strData
Text1.Text = strData & vbCrLf & Text1.Text
End Sub
===========================================
end code for the SERVER
===========================================

I hope you guys can help me, because I really want to learn VB, and this is my bottleneck. My brain isn't thinking correctly right now, so... I'll get back at it tomorrow.








 
I have done quite a lot with the winsock control and i would recomend having a single listening winsock and an array, with which you connect. ie

Sub Form_Load()
Dim i As Integer
For i = 1 to NUMSOCKETS
Load sckConnection(i)
Next i
sckListener.Listen
End Sub

Sub sckListener_ConnectionRequest(ByVal requestID As Long)
Dim i As Integer
For i = 0 to NUMSOCKETS
If sckConnection(i).State = sckClosed Then
sckConnection(i).Accept requestID
Exit Sub
End If
Next i
End Sub

Sub sckConnection_DataArrival(Index As Integer, byVal bytesTotal As Long)
Dim sMessage As String
Dim i As Integer
sckConnection(Index).GetData sMessage, vbString
For i = 0 to NUMSOCKETS
If (sckConnection(i).State = sckConnected) And Not i = Index Then sckConnection(i).SendData sMessage
skcConnection(i).SendData sMessage
End If
Next i
End Sub

This is the rough sort of thing...
 
thank you kindly for your prompt reply ICISYD, I think that should solve my problem...and I will try to implement it in the next few minutes(hopefully), unfortunately, I don't quite understand the code in the Data_arrival sub. What I don't get is the condition ...And Not i = Index Then sckConnection(i).SendData sMessage... I mean, if the socket is connected and it is different than the current(index) socket, then send the same sMessage that was received by the previous socket??? Either I'm not reading the code correctly or I'm plain old simply DUMB.

The latter variant is the most probable... :)

Thank you again, for the time and effort. I really appreciate it...
ARES

 
oh, a couple of things more:
what do I name my Winsock control on the server application, because I get an error while trying to compile:

&quot;Procedure declaration does not match description of event or procedure having same name&quot; at the compilation of sckConnection_DataArrival...

oh, what is NUMSOCKETS? I mean I could guess that it is a variable or a constant of some kind, but how is its value manipulated, or by what process?

P.S> I've told you, I'm still a beginner, a newbie, so I could use all the help I can get...

Thank you....
ARES
 
It is a slightly confusing way of saying send the message to all sockets exept the one that recieved it. sckConnection(Index) is the socket that has just recieved the data, all that line does is check that the message is not being sent back to the place it came from.
 
sckConnection is a winsock with Index = 0
sckListener is a winsock with Port = 666

In the declarations of the code you should put:

Const NUMSOCKETS = x 'Where x is max number of connections.
 
thank you kindly. this solves my problem.

you're the man...

thank you again.... it works great.

now I can focus on other aspects of my application, i.e. how to &quot;kick&quot; users, but I'm not really sure about implementing this option to the server, because it's a &quot;friendly&quot; chat environment, but, as everywhere, there are all kinds of people, and I'm guessing, that whoever swears or smth, should be kicked and banned.

I figured that I should use some files on the server machine, and store users there, history (logs) and stuff.

but with the multiple connections problem solved, this is much easier.... now.

I'm eternally grateful.

ARES
 
one more question:
the compiler doesn't say anything, but I think there is a useless line here:

If (sckConnection(i).State = sckConnected) And Not i = Index Then sckConnection(i).SendData sMessage
sckConnection(i).SendData sMessage
End If

the line sckConnection(i).sendData sMessage is duplicate, so this is what I think it does:

if the state of the socket is &quot;connected&quot; and its number isn't the one that sent the data, then send the sMessage. As you said, send the received message, to all the other sockets, except the one that originated the message. So, what use is it to do that 2(two) times? I don't get it...

anyway, without that line, the program works juuuust fine, thank you.

ARES
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top