• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 526
  • Last Modified:

MultiThreading Winsock Question

Hello!

I am working on a game. The server can accept 5 winsock connections say ports 9991-9995. However, the client and the server are actually the in the same .exe file meaning anyone can be the server. So if that person is the server he will execute the following

        With frmGame.Winsock1(1)
            .LocalPort = 9991
            .Listen
        End With
   
        With frmGame.Winsock1(2)
            .LocalPort = 9992
            .Listen
        End With

But if he is the client only, the will skip this and execute a connection to one of those ports.

       With Winsock1(1)          
             .RemoteHost = ServerIP
             .RemotePort = ServerPort
             .Connect
        End With

How do I implement it properly? So when a person joins he is connected to the an available port. When someone quits, I know which ports r free that can be assigned. How do i send a message to all of them at a time?

Do i need to use threading? If so how? I tried but it fails on the 'listen' of IMSWinsockControl part.
0
Delng
Asked:
Delng
  • 5
  • 4
1 Solution
 
SilentRageCommented:
I've done this exact thing - making a Online chess game that allows two people to play against each other over the net - with as many people watching as you want.  Both server and client is incorporated into the same program.

Everything on my site is opensource, so for example code you may go here: http://serialcoders.sytes.net and find the "Online Chess" link.

Now for a brief explanation of the methodology I used:

First of all, I have placed 1 Winsock control on my form with an index of 0.  When I'm a client, that control will connect to the server.  From then on, I KNOW it is acting as a client from then on in the code because the Winsock(0).State is equal to sckConnected.  When I'm a server, I will set index 0 to listen for incoming connections.  All connections are then assigned a loaded winsock control with an index 1 greater than the upper bound of the winsock collection.

So here's example code:

Under my "act as host" menu i have this snippet of code:

Winsock(0).LocalPort = Val(Port)
On Error Resume Next
    Winsock(0).Listen
    If Err.Number > 0 Then
        Winsock_Error 0, Err.Number, Err.Description, 0, "", "", 0, False
        Exit Sub
    End If
On Error Resume Next

Under my "act as client" menu, I have this snippet of code:

'Fields(0) is the host, Fields(1) is the port
Winsock(0).Connect Fields(0), Fields(1)

Some code from my incoming connection event:

Index = Winsock.UBound + 1
'Setup the new connection
Load Winsock(Index)
Winsock(Index).Accept requestID
Winsock(Index).Tag = "CLIENT" & Index 'identifier for his user
Winsock(Index).SendData "NAMES CLIENT" & Index & Names & vbCrLf 'some of the state information this client needs to know about

The code from my SendClients subroutine.

Public Sub SendClients(ByVal Data As String)
    'loop through each existing winsock control
    For Each WS In frmMain.Winsock
        'do not send to index 0 (that's the server)
        If WS.Index > 0 Then
            WS.SendData CStr(Data)
            DoEvents
        End If
    Next
End Sub

Some code from my connection closed routine

Public Sub Winsock_Close(Index As Integer)
    'If index is 0, then we are the client
    If Index = 0 Then
        Winsock(0).Close
    Else
        'otherwise, we're the server, cleanup this client
        KillClient Index, ""
    End If
End Sub

Some code from my KillClient subroutine

Public Sub KillClient(Index As Integer, ByVal Msg As String)
    User = Winsock(Index).Tag
    'close the connection
    Winsock(Index).Close
    'remove the control (required cause of how I coded SendClients)
    Unload Winsock(Index)

    'notify all the clients that this client is dead
    SendClients "QUIT " & User & " " & Msg & vbCrLf
End Sub

Well that should give ya all you need to know.  As I said, for full example source refer to my website.
0
 
DelngAuthor Commented:
You used the same port for all connections right?
As...i notice u used

For Each WS In frmMain.Winsock

Where did you define it (WS)? Can't find it...is there a missing file?
0
 
SilentRageCommented:
I never defined it, so it's variant.  That's an older project before I started using Option Explicit.

to be explicit:

Dim WS As Winsock
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
SilentRageCommented:
you listen on a port the host user specifies.  then everybody connects to that IP/port.
0
 
DelngAuthor Commented:
Need to ask you something again. The server uses winsock(0) while the clients use winsock(i) where i > 0 right?
0
 
SilentRageCommented:
yep.  when you're a client though, Winsock(0) is what makes the connection.  How the 0 index is put to use is the clue throughout my entire program on whether I'm acting as client or server.
0
 
DelngAuthor Commented:
Thanks!

I have a problem now. Lets say 3 clients have connected to the server. One of them quits. The SendClients now will have a problem. This is because one of the Winsock of that client that has quit no longer exists because it has been unloaded. How can I solve this problem?
0
 
DelngAuthor Commented:
Oh I know..haha it works with the For Each thingy...
Thanks Dude...anymore questions I post here yah? Thanks!
0
 
SilentRageCommented:
you can also post questions on my board if you like.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now