MultiThreading Winsock Question

Posted on 2003-03-30
Medium Priority
Last Modified: 2013-11-13

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
        End With
        With frmGame.Winsock1(2)
            .LocalPort = 9992
        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
        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.
Question by:Delng
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4

Accepted Solution

SilentRage earned 300 total points
ID: 8233340
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
    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)
        End If
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
        '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
    '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.

Author Comment

ID: 8233548
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?

Expert Comment

ID: 8233580
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
Industry Leaders: 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!


Expert Comment

ID: 8233583
you listen on a port the host user specifies.  then everybody connects to that IP/port.

Author Comment

ID: 8233669
Need to ask you something again. The server uses winsock(0) while the clients use winsock(i) where i > 0 right?

Expert Comment

ID: 8233725
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.

Author Comment

ID: 8234678

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?

Author Comment

ID: 8234766
Oh I know..haha it works with the For Each thingy...
Thanks Dude...anymore questions I post here yah? Thanks!

Expert Comment

ID: 8235172
you can also post questions on my board if you like.

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
This video teaches viewers about errors in exception handling.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question