Home All Groups Group Topic Archive Search About

MS Winsock Control ports don't free up

Author
24 Feb 2007 3:22 AM
Jimmy B
Sorry to post this here, but I haven't been able to find anything online
about this one.  I've had a small client/server app. for years where the
client just uses WSClient.Connect to automatically select a free port and
connect to the remote system.  That's great and is how I want it, but let's
say we need to close the connection with WSClient.Close and reconnect?  Even
though I've done a .Close, the .Connect advances to the next consecutive
port #.  And if I close my app. and re-run it, the previous ports are still
apparently locked and .Connect chooses a free port from where it left off
before.

I know there must be a limit to how many Winsock ports there are, so is
there a way I can tell Winsock that it can truly free up that port so it can
be reused, either by my app. or a different one?  And I like the MSWinsock
OCX just fine, so I don't want to use API for communication, but if there's
an API to free the port using .SocketHandle, that would be just fine!


Thanks tons in advance!

Author
24 Feb 2007 2:00 PM
Bob Butler
"Jimmy B" <a***@anon.com> wrote in message
news:Ow9C4L8VHHA.1036@TK2MSFTNGP03.phx.gbl
> Sorry to post this here, but I haven't been able to find anything
> online about this one.  I've had a small client/server app. for years
> where the client just uses WSClient.Connect to automatically select a
> free port and connect to the remote system.  That's great and is how
> I want it, but let's say we need to close the connection with
> WSClient.Close and reconnect?  Even though I've done a .Close, the
> .Connect advances to the next consecutive port #.  And if I close my
> app. and re-run it, the previous ports are still apparently locked
> and .Connect chooses a free port from where it left off before.

How long have you waited before checking again?  Ports are normally left in
a "linger" for a short period to allow time for both ends of the connection
to deal with any data in transit and clean up.  After that the port becomes
available again.


--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
25 Feb 2007 8:29 PM
Jimmy B
Actually I'm reconnecting real quick, like 100ms if there's a disconnection.
Every time there's a disconnection, there's a timer that just tries to
connect using the next available port, which in reality happens about every
half second.  I'll try to make it 2 - 3 seconds.  You think that will
actually help?  Because here's the thing, if I leave this running (and kill
the server so it can't connect), the ports keep incrementing.  if old ports
are freed up after a certain amount of time, I'd think it would eventually
start start near the beginning.

I will do some experimenting and see what I come up with.  Thanks!!
Author
25 Feb 2007 7:00 AM
AmiDaniel
Show quote Hide quote
On Feb 23, 8:22 pm, "Jimmy B" <a***@anon.com> wrote:
> Sorry to post this here, but I haven't been able to find anything online
> about this one.  I've had a small client/server app. for years where the
> client just uses WSClient.Connect to automatically select a free port and
> connect to the remote system.  That's great and is how I want it, but let's
> say we need to close the connection with WSClient.Close and reconnect?  Even
> though I've done a .Close, the .Connect advances to the next consecutive
> port #.  And if I close my app. and re-run it, the previous ports are still
> apparently locked and .Connect chooses a free port from where it left off
> before.
>
> I know there must be a limit to how many Winsock ports there are, so is
> there a way I can tell Winsock that it can truly free up that port so it can
> be reused, either by my app. or a different one?  And I like the MSWinsock
> OCX just fine, so I don't want to use API for communication, but if there's
> an API to free the port using .SocketHandle, that would be just fine!
>
> Thanks tons in advance!


Sorry to ask something so incredibly obvious (though I often find that
most of my problems are obvious once I see the solution), but you are
reseting the WinSock's port each time you reconnect, right? For
instance, if you're trying to connect to port 21, you'll need to
specify that each time before you invoke .Connect.

If that doesn't work for you, you might check out "WSACleanup" and/or
"setsockopt" from the "WSOCK32" lib. Not sure if it will do what you
want even remotely, but it seems to be the most promising thing I can
find documented in the win api.

--
Daniel Cannon
Author
25 Feb 2007 8:37 PM
Jimmy B
Well like I said, I'm just letting the MS Winsock control "find" the next
available port, so I'm not selecting a certain port.  I haven't needed to
select just one port.  Now I do use a certain port on the server and that
works fine because I specify it and I don't let MS Winsock choose the port
automatically.

I'm going to try a few things and see where I'm going wrong.  Perhaps the MS
Winsock OCX chooses the very next port if the "current" local port is
unavailable.  So maybe I could tell it to try and start at a lower port and
go from there.  I'll look at using API's like WSACleanup if I can't get this
to work.

I should probably have posted my code, but it's kind of messy right now.  :)
Author
25 Feb 2007 9:21 PM
AmiDaniel
On Feb 25, 1:37 pm, "Jimmy B" <a***@anon.com> wrote:
> I should probably have posted my code, but it's kind of messy right now.  :)

No worries -- you're talking to the king of messy code :).

--
Daniel Cannon
Author
25 Feb 2007 10:16 PM
Bob O`Bob
Jimmy B wrote:
Show quoteHide quote
> Well like I said, I'm just letting the MS Winsock control "find" the next
> available port, so I'm not selecting a certain port.  I haven't needed to
> select just one port.  Now I do use a certain port on the server and that
> works fine because I specify it and I don't let MS Winsock choose the port
> automatically.
>
> I'm going to try a few things and see where I'm going wrong.  Perhaps the MS
> Winsock OCX chooses the very next port if the "current" local port is
> unavailable.  So maybe I could tell it to try and start at a lower port and
> go from there.  I'll look at using API's like WSACleanup if I can't get this
> to work.
>
> I should probably have posted my code, but it's kind of messy right now.  :)


I still haven't seen any adequate explanation for why you would even *care*
what assigned port number it gets.

I believe you are theorizing nebulous "problems" which don't actually exist.



    Bob
--
Author
26 Feb 2007 3:39 AM
Jimmy B
Well, I guess I didn't actually test this before, but I did today.  And when
I let it keep connecting (without being able to connect because the remote
machine is off), it gets to around port 60,000 and the entire system goes
flaky and I have to reset.  So there's definitely a port limit.

That's the thing, there could be a time when the server might be down for
extended periods of time but I don't want my program to stop trying, plus I
don't want to use any specific port on the local machine in case some other
software is using it, and there's no need to.  That's why I have the MS
Winsock control "find" the next free port.

So there you go, real problem, real worry.  I'm working on it now and I hope
to fix it soon!
Author
26 Feb 2007 4:38 AM
Bob O`Bob
Jimmy B wrote:
> Well, I guess I didn't actually test this before, but I did today.  And when
> I let it keep connecting (without being able to connect because the remote
> machine is off), it gets to around port 60,000 and the entire system goes
> flaky and I have to reset.  So there's definitely a port limit.
>

Try your testing again, but starting at 65,500 . . .


Show quoteHide quote
> That's the thing, there could be a time when the server might be down for
> extended periods of time but I don't want my program to stop trying, plus I
> don't want to use any specific port on the local machine in case some other
> software is using it, and there's no need to.  That's why I have the MS
> Winsock control "find" the next free port.
>
> So there you go, real problem, real worry.  I'm working on it now and I hope
> to fix it soon!
Author
26 Feb 2007 6:06 AM
Jimmy B
Um, it seems you can't start at a certain port # unless you set it manually,
but then you could be picking ports that aren't free.

I made some sample code for anyone to try.  Just start a new project, add
the MS Winsock control and run it.


Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Form_Load()
    'Set remote host and port to connect to.
    'In this case, just the local machine for testing.
    Winsock1.RemoteHost = "127.0.0.1"
    Winsock1.RemotePort = 4000

    'Set local port to 0
    'From VB6's docs:
    '"Port 0 is often used to establish connections between computers
    dynamically.
    'For example, a client that wishes to be "called back" by a server can
    use
    'port 0 to procure a new (random) port number, which can then be given
    to
    'the remote computer for this purpose."

    Winsock1.LocalPort = 0
    Winsock1.Connect
End Sub

Private Sub Winsock1_Error(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)
    Print "Error: " & Description & " " & Now

    Winsock1.Close 'Shouldn't this free up this port?

    DoEvents    ' Allow us to stop
    'Sleep 5000  ' Cheap and easy pause for the sake of example

    Winsock1.Connect
    Me.Cls
    Print "Connecting to: " & Winsock1.RemoteHost & ", port " &
    Winsock1.RemotePort & _
            " , Local Port: " & Winsock1.LocalPort
    Print "And I'll continue to use the next port until I crash this
    computer."
    Print "Try letting me run until I get to 70,000." & vbNewLine
End Sub

Private Sub Winsock1_Close()
    MsgBox "Close event fired."
End Sub

Private Sub Winsock1_Connect()
    MsgBox "Connect event fired."
End Sub