Results 1 to 20 of 20

Thread: Winsock Multiple Connections

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    May 2004
    Posts
    566

    Winsock Multiple Connections

    I'm having trouble accepting multiple connections in Winsock.

    Here's the code:
    Code:
    Private Sub Form_Load()
        wsServer(0).LocalPort = 4500
        wsServer(0).Listen
    End Sub
    
    Private Sub wsServer_Close(Index As Integer)
        wsServer(Index).Close
    End Sub
    
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
        Dim K As Integer
    
        For K = 1 To wsServer.UBound
            If wsServer(K).State = sckClosed Then Exit For
        Next K
    
        If K = wsServer.UBound + 1 Then
            Load wsServer(wsServer.UBound + 1)
        End If
    
        wsServer(K).Accept requestID
    End Sub
    It accepts one(1) connection but a second(2nd) cannot connect.

    Am I doing something wrong?
    if you helped me, consider yourself thanked

  2. #2
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Winsock Multiple Connections

    I usually do it a little differently but try this:

    Code:
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
        Dim K As Integer
        
        If wsServer.ubound = 0 Then
            Load wsServer(1)
            wsServer(1).Accept requestID
        Else
            For K = 1 To wsServer.ubound
                If wsServer(K).State = sckClosed Then Exit For
            Next K
        
            If K = wsServer.ubound Then
                K = K + 1
                Load wsServer(K)
            End If
        
            wsServer(K).Accept requestID
        End If
    End Sub

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    May 2004
    Posts
    566

    Re: Winsock Multiple Connections

    Thanks for the reply.

    It says: "Control array element '2' doesn't exist", on the code below:
    Code:
    wsServer(K).Accept requestID
    if you helped me, consider yourself thanked

  4. #4
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    I think there was a typo in DigiRev's example. The snippet of code prior to the Load should look like this, I believe
    Code:
            '
            ' If a closed socket wasn't found
            ' then K will be the element number we
            ' want to load. If we did find a closed socket
            ' then element K is already loaded
            '
            If K > wsServer.ubound Then
                Load wsServer(K)
            End If
    Last edited by Doogle; Mar 24th, 2008 at 01:08 AM.

  5. #5
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Winsock Multiple Connections

    Well, according to that code, k will never be > than .UBound

    Try this

    Code:
    Private Function NextSocket() As Integer
        Dim i As Integer, intRet As Integer
        If wsServer.UBound = 0 Then
            Load wsServer(1)
            NextSocket = 1
        Else
            For i = 1 To wsServer.UBound
                If wsServer(i).State = sckClosed Then
                    intRet = i
                    Exit For
                End If
            Next i
            If intRet > 0 Then
                NextSocket = intRet
            Else
                intRet = wsServer.UBound + 1
                Load wsServer(intRet)
                NextSocket = intRet
            End If
        End If
    End Function
    
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
        Dim i As Integer
        i = NextSocket
        If i > 0 Then
            wsServer(i).Accept requestID
        End If
    End Sub

  6. #6
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    Quote Originally Posted by DigiRev
    Well, according to that code, k will never be > than .UBound
    I beg to differ
    Code:
    Private Sub Form_Load()
    Dim intI As Integer
    Dim intK As Integer
    intK = 100
    For intI = 1 To 10
        If intI = intK Then Exit For
    Next intI
    Debug.Print intI
    End Sub
    If you run the above you'll see that intI = 11. When a For / Next loop completes, the loop control variable is one more then the ending condition. (for positive values). This is because the increment and test happen at the 'Next'.

  7. #7
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: Winsock Multiple Connections

    If wsServer.ubound = 0 Then is unnecessary since K iteration starts at one. My winsock is a bit hazy but wouldn't it be better (from debugging POV) to reset port to zero first so it will be auto-assigned (e.g. cases wherein listening port number assigned at design time rather than run-time so all created instances will default to that port number instead of zero)?

    Code:
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
       Dim K As Integer
        
       For K = 1 To wsServer.ubound
          If wsServer(K).State = sckClosed Then Exit For
       Next K
        
       If K > wsServer.ubound Then
          Load wsServer(K)
       End If
       
       wsServer(K).LocalPort = 0    
       wsServer(K).Accept requestID
    End Sub

  8. #8
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Winsock Multiple Connections

    Quote Originally Posted by Doogle
    I beg to differ
    Code:
    Private Sub Form_Load()
    Dim intI As Integer
    Dim intK As Integer
    intK = 100
    For intI = 1 To 10
        If intI = intK Then Exit For
    Next intI
    Debug.Print intI
    End Sub
    If you run the above you'll see that intI = 11. When a For / Next loop completes, the loop control variable is one more then the ending condition. (for positive values). This is because the increment and test happen at the 'Next'.
    ah you're right

    I thought it'd end at 10, my mistake

  9. #9
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Winsock Multiple Connections

    Quote Originally Posted by leinad31
    If wsServer.ubound = 0 Then is unnecessary since K iteration starts at one. My winsock is a bit hazy but wouldn't it be better (from debugging POV) to reset port to zero first so it will be auto-assigned (e.g. cases wherein listening port number assigned at design time rather than run-time so all created instances will default to that port number instead of zero)?

    Code:
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
       Dim K As Integer
        
       For K = 1 To wsServer.ubound
          If wsServer(K).State = sckClosed Then Exit For
       Next K
        
       If K > wsServer.ubound Then
          Load wsServer(K)
       End If
       
       wsServer(K).LocalPort = 0    
       wsServer(K).Accept requestID
    End Sub
    All Winsocks in the array will use the same local port as the first one

  10. #10
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    Generally it's not a good idea to set the LocalPort property in anything other than the Listening socket. TCP will allocate an almost random local port if none is specified. This is because it can take up to 4 minutes for a used local port to be released. Attempting to re-use the local port within 4 mins. can cause unexpected errors.

    (see here: http://support.microsoft.com/kb/173619)

  11. #11
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: Winsock Multiple Connections

    Yes, your reusing socket with localport assigned (the for loop), so localport = 0 is necessary to prevent address in use.

  12. #12
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    No, the Port is in use by the Server Program and all the sockets should (must)communicate via the same Local Port (that's the Port the client is connecting to). The TCP port is the unique TCP 'address' of the application. Thus something like '192.168.0.12:4000' (IP Address:Tcp Port) uniquely defines a TCP application on the Network.

    Within the application the port will be connected to multiple clients. If you attempted to start another application using the same local port you'd get the 'Address in use' message. Basically, the IP Address identifies the Machine and the TCP Port identifies the Application. Each must be unique within a given Computer.
    Last edited by Doogle; Mar 24th, 2008 at 03:07 AM.

  13. #13
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: Winsock Multiple Connections

    K. I was thinking of local test using loopback 127.0.0.1. It would error then.

  14. #14
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    No it wouldn't. Let's say 127.0.0.1 is listening on Port 4000 (that would be the 'Listner' applications LocalPort). The 'connecting application' would set it's RemotePort to 4000 - leaving the 'connecting' application's LocalPort to be allocated by TCP, eg 23456. Hence no conflict in LocalPort usage.

    The listner's TCP Address is 127.0.0.1:4000 the connecting application is 127.0.0.1:23456. If another instance of the connecting application is run on the same machine, TCP will allocate a LocalPort that is not in use, eg 23457, and that application, as far as TCP is concerned, is unique. (127.0.0.1:23457) However, they're both communicating with the server's port 4000 through their RemotePort setting.
    Last edited by Doogle; Mar 24th, 2008 at 03:19 AM.

  15. #15
    Lively Member reisve's Avatar
    Join Date
    Mar 2005
    Posts
    118

    Re: Winsock Multiple Connections

    I can't recall exactely, but had a similar problem. There is a property you set in the WINSOCK so every new connection will get a new (ramdom?) port. Otherwise, Winsock will only accept a connection at the time.

  16. #16
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Winsock Multiple Connections

    If you don't set the LocalPort property in the 'connecting' application, TCP will allocate a free one. That ensures that you will not confilict with any other open Local Ports. If you set the Local Port yourself then you run the risk of conflicts and "Address in Use" errors and the "can't resuse for 4 minutes" 'feature'.

  17. #17

    Thread Starter
    Fanatic Member
    Join Date
    May 2004
    Posts
    566

    Re: Winsock Multiple Connections

    So, which should fix the problem? Now I'm confused
    if you helped me, consider yourself thanked

  18. #18
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: Winsock Multiple Connections

    Code:
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
       Dim K As Integer
        
       For K = 1 To wsServer.ubound
          If wsServer(K).State = sckClosed Then Exit For
       Next K
        
       If K > wsServer.ubound Then
          Load wsServer(K)
       End If
       
       wsServer(K).Accept requestID
    End Sub

  19. #19
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Winsock Multiple Connections

    For TCP the end doing a Listen is the "server" and must be sure that it sets LocalPort to the port to Listen on. This can be done explicitly (LocalPort property), via a Bind method parameter, or a Listen method parameter. The Listen operation does not use RemotePort.

    The end doing the Connect is the "client" and should set LocalPort to 0 and RemotePort to the server's listening port. This can be done explicitly or via a parameter to the Connect method. When the Connect begins TCP sees the 0 and assigns an available ephemeral port number (if available) automatically.

    When the server Accepts the connection request, the Accepting Winsock gets its LocalPort set to the Listen port (automatically) and its RemotePort set to the client's ephemeral port (automatically).


    Every TCP "connection" is identified internally by TCP as a 4-tuple (2 endpoint pairs): [[LocalIP, LocalPort], [RemoteIP, RemotePort]]. If a client fails to reset its LocalPort (preferably to 0) before connecting to the same server endpoint [RemoteIP, RemotePort] again it will get an error. Even if the client sets LocalPort to 0, if the ephemeral port pool is exhausted it will get an error. Windows normally reserves ~ 4000 ports per IP address as its ephemeral port pool. Most PCs only have one IP address though.

    This is what takes a "4 minute delay" to be retired: the entry in TCP's connection list. It is a TCP/IP standard and meant to help TCP "connections" survive brief interruptions in lower-level connectivity between the endpoints.

    See TCP Connection States and Netstat Output or dig out your Comer books.

  20. #20
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Winsock Multiple Connections

    Quote Originally Posted by emyztik
    So, which should fix the problem? Now I'm confused
    Use this:
    Quote Originally Posted by DigiRev
    Well, according to that code, k will never be > than .UBound

    Try this

    Code:
    Private Function NextSocket() As Integer
        Dim i As Integer, intRet As Integer
        If wsServer.UBound = 0 Then
            Load wsServer(1)
            NextSocket = 1
        Else
            For i = 1 To wsServer.UBound
                If wsServer(i).State = sckClosed Then
                    intRet = i
                    Exit For
                End If
            Next i
            If intRet > 0 Then
                NextSocket = intRet
            Else
                intRet = wsServer.UBound + 1
                Load wsServer(intRet)
                NextSocket = intRet
            End If
        End If
    End Function
    
    Private Sub wsServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
        Dim i As Integer
        i = NextSocket
        If i > 0 Then
            wsServer(i).Accept requestID
        End If
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width