|
|
|
date: Tue, 20 Dec 2005 13:40:57 +0200,
group: microsoft.public.platformsdk.networking
back
Re: Winsock API socket value "reuse" ?
BTW to close socket correctly you need to use shutdown() too , look at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/graceful_shutdown_linger_options_and_socket_closure_2.asp
( aware of wrap )
Arkady
"Arkady Frenkel" wrote in message
news:%23Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl...
> Hi!
> "John Smith" wrote in message
> news:eDc6$oVBGHA.3396@tk2msftngp13.phx.gbl...
>> Hi,
>> I am hunting down a bug in some software and the hunt raises the
>> following question - assuming I have the following (pseudo) code:
>>
>> Thread A
>> =======
>> ...setup a listenSocket for accepting incoming connections...
>>
>> while (true) {
>>
>> SOCKET c=accept(listenSocket, NULL, NULL);
>> ..spawn a thread (B) and pass it the accepted socket value
>> }
>>
>> Thread B
>> ======
>> ....use the passed socket and (maybe) call "closesocket" when finished
>> closesocket(c); // just making sure again before exiting the thread
>>
>> - My question is this - if thread (B) calls "closesocket" TWICE with the
>> same value, then this raises some questions:
>>
>> 1. is the second call "safe" - i.e., assuming there was no
>> multi-threading (see question 2) is the second call to "closesocket" same
>> as a NOOP...(I suspect not, but please confirm it).
>>
> No problem to call it twice IIRC
>> 2. since threads A/B run concurrently - if the "accept" call "reuses"
>> previously closed value (does it ?) then thread B might close a socket
>> that has just been accepted if by some chance the closed socket value
>> (from first call) is exactly the one just assigned to the accepted
>> connection
>
> Yes
>>
>> 3. are the socket values/handles "reused" immediately or is there a
>> (configurable ?) "freeze" time ?
>>
> That happen by default after 2 MSL which is 240 sec by default
> You do can change registry key (
> HKEY_LOCAL_MACHINE\System\CurrectControlSet\services\Tcpip\Parameters\\TcpTimedWaitDelay
> ) for it , but that strongly not recommended because that system-wide
> parameter and not socket specific , as such one look at linger option for
> socket
> HTH
> Arkady
>
>> I welcome your thoughts/remarks on these issues
>> Thanks.
>>
>>
>
>
date: Wed, 21 Dec 2005 09:32:28 +0200
author: Arkady Frenkel
Re: Winsock API socket value "reuse" ?
BTW I closesocket on already close socket will return error 10038 (
WSAENOTSOCK - already :) ) in advance
Arkady
"Arkady Frenkel" wrote in message
news:uPvTbCgBGHA.208@tk2msftngp13.phx.gbl...
> BTW to close socket correctly you need to use shutdown() too , look at
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/graceful_shutdown_linger_options_and_socket_closure_2.asp
> ( aware of wrap )
>
> Arkady
>
> "Arkady Frenkel" wrote in message
> news:%23Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl...
>> Hi!
>> "John Smith" wrote in message
>> news:eDc6$oVBGHA.3396@tk2msftngp13.phx.gbl...
>>> Hi,
>>> I am hunting down a bug in some software and the hunt raises the
>>> following question - assuming I have the following (pseudo) code:
>>>
>>> Thread A
>>> =======
>>> ...setup a listenSocket for accepting incoming connections...
>>>
>>> while (true) {
>>>
>>> SOCKET c=accept(listenSocket, NULL, NULL);
>>> ..spawn a thread (B) and pass it the accepted socket value
>>> }
>>>
>>> Thread B
>>> ======
>>> ....use the passed socket and (maybe) call "closesocket" when
>>> finished
>>> closesocket(c); // just making sure again before exiting the
>>> thread
>>>
>>> - My question is this - if thread (B) calls "closesocket" TWICE with the
>>> same value, then this raises some questions:
>>>
>>> 1. is the second call "safe" - i.e., assuming there was no
>>> multi-threading (see question 2) is the second call to "closesocket"
>>> same as a NOOP...(I suspect not, but please confirm it).
>>>
>> No problem to call it twice IIRC
>>> 2. since threads A/B run concurrently - if the "accept" call "reuses"
>>> previously closed value (does it ?) then thread B might close a socket
>>> that has just been accepted if by some chance the closed socket value
>>> (from first call) is exactly the one just assigned to the accepted
>>> connection
>>
>> Yes
>>>
>>> 3. are the socket values/handles "reused" immediately or is there a
>>> (configurable ?) "freeze" time ?
>>>
>> That happen by default after 2 MSL which is 240 sec by default
>> You do can change registry key (
>> HKEY_LOCAL_MACHINE\System\CurrectControlSet\services\Tcpip\Parameters\\TcpTimedWaitDelay
>> ) for it , but that strongly not recommended because that system-wide
>> parameter and not socket specific , as such one look at linger option for
>> socket
>> HTH
>> Arkady
>>
>>> I welcome your thoughts/remarks on these issues
>>> Thanks.
>>>
>>>
>>
>>
>
>
date: Wed, 21 Dec 2005 10:40:01 +0200
author: Arkady Frenkel
Re: Winsock API socket value "reuse" ?
In article <#Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl>, "Arkady Frenkel"
wrote:
>> - My question is this - if thread (B) calls "closesocket" TWICE with the
>> same value, then this raises some questions:
>>
>> 1. is the second call "safe" - i.e., assuming there was no
>> multi-threading (see question 2) is the second call to "closesocket" same
>> as a NOOP...(I suspect not, but please confirm it).
>>
>No problem to call it twice IIRC
Sorry - that's wrong advice.
The socket handle may very well be reused before the first closesocket() has
even returned to your application, and you'll be closing a socket that you
don't actually own.
You have to be extraordinarily careful to make sure that closesocket() is only
ever called on sockets that you own, and that you know are not going to be
referenced again by your code (except as a completely new socket).
Socket handle reuse has typically been _very_ aggressive in Windows; I haven't
tested it in years, but it's fairly easy to test - just keep opening and
closing sockets more or less randomly, and look to see how quickly a new
socket will get created using the old handle.
>> 3. are the socket values/handles "reused" immediately or is there a
>> (configurable ?) "freeze" time ?
>>
>That happen by default after 2 MSL which is 240 sec by default
No - you are confusing sockets and socket handles. Sockets remain in
TIME_WAIT state after they are closed; socket handles do not. The socket
handle for the socket that remains in TIME_WAIT state is _not_ maintained by
the stack after closesocket() has been called - closesocket specifically
disassociates the socket handle from the socket (and does not necessarily
close the socket).
Alun.
~~~~
[Please don't email posters, if a Usenet response is appropriate.]
--
Texas Imperial Software | Find us at http://www.wftpd.com or email
23921 57th Ave SE | alun@wftpd.com.
Washington WA 98072-8661 | WFTPD, WFTPD Pro are Windows FTP servers.
Fax/Voice +1(425)807-1787 | Try our NEW client software, WFTPD Explorer.
date: Fri, 23 Dec 2005 19:39:14 GMT
author: lid (Alun Jones)
Re: Winsock API socket value "reuse" ?
"Alun Jones" <alun@texis.invalid> wrote in message
news:RqKdnfmEl5KyzzHeRVn-pw@comcast.com...
> In article <#Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl>, "Arkady Frenkel"
> wrote:
>>> - My question is this - if thread (B) calls "closesocket" TWICE with the
>>> same value, then this raises some questions:
>>>
>>> 1. is the second call "safe" - i.e., assuming there was no
>>> multi-threading (see question 2) is the second call to "closesocket"
>>> same
>>> as a NOOP...(I suspect not, but please confirm it).
>>>
>>No problem to call it twice IIRC
>
> Sorry - that's wrong advice.
Taht was not advice but answer you and Eugene didn't understand what I mean
, I too stand that it's not good practice to close already , but that
practically closed without any problems if it done correctly...
>
> The socket handle may very well be reused before the first closesocket()
> has
> even returned to your application, and you'll be closing a socket that you
> don't actually own.
>
No, you can close only your sockets ( or created by your or received through
WSADuplicateSocket() ) otherwise error will returned
> You have to be extraordinarily careful to make sure that closesocket() is
> only
> ever called on sockets that you own, and that you know are not going to be
> referenced again by your code (except as a completely new socket).
>
Handles you have is your own only and not system wide , that's why if you
want to use that socket in different process that have to be used with
WSADuplicateSocket() and closesocket for other-then-your-process will return
WSAENOTSOCK error.
> Socket handle reuse has typically been _very_ aggressive in Windows; I
> haven't
> tested it in years, but it's fairly easy to test - just keep opening and
> closing sockets more or less randomly, and look to see how quickly a new
> socket will get created using the old handle.
>
>>> 3. are the socket values/handles "reused" immediately or is there a
>>> (configurable ?) "freeze" time ?
>>>
>>That happen by default after 2 MSL which is 240 sec by default
>
> No - you are confusing sockets and socket handles. Sockets remain in
> TIME_WAIT state after they are closed; socket handles do not. The socket
> handle for the socket that remains in TIME_WAIT state is _not_ maintained
> by
> the stack after closesocket() has been called - closesocket specifically
> disassociates the socket handle from the socket (and does not necessarily
> close the socket).
No, I checked that on Windows CE , where socket handle's receive sequential
numbers in the process ( 0,1,2... ) and handle was not reused up to socket
was open ( really for 32bit system it have 4 billion numbers before reuse
:) ) , that will be funny to check that on 64 bit system ( AFAIK really not
exist yet such :) )
Arkady
>
> Alun.
> ~~~~
>
> [Please don't email posters, if a Usenet response is appropriate.]
> --
> Texas Imperial Software | Find us at http://www.wftpd.com or email
> 23921 57th Ave SE | alun@wftpd.com.
> Washington WA 98072-8661 | WFTPD, WFTPD Pro are Windows FTP servers.
> Fax/Voice +1(425)807-1787 | Try our NEW client software, WFTPD Explorer.
date: Sat, 24 Dec 2005 10:59:26 +0200
author: Arkady Frenkel
Re: Winsock API socket value "reuse" ?
Thank you all for the replies - I suspected as much, but it is always good
practice to validate one's suspicions by one's peers. FYI, I corrected the
offending code and it seems to work just fine - i.e., my conclusion is to
agree with what has been said: always make sure you close sockets, only
ONCE -> those you "own"
"Arkady Frenkel" wrote in message
news:uDhc8gGCGHA.3292@TK2MSFTNGP09.phx.gbl...
>
> "Alun Jones" <alun@texis.invalid> wrote in message
> news:RqKdnfmEl5KyzzHeRVn-pw@comcast.com...
>> In article <#Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl>, "Arkady Frenkel"
>> wrote:
>>>> - My question is this - if thread (B) calls "closesocket" TWICE with
>>>> the
>>>> same value, then this raises some questions:
>>>>
>>>> 1. is the second call "safe" - i.e., assuming there was no
>>>> multi-threading (see question 2) is the second call to "closesocket"
>>>> same
>>>> as a NOOP...(I suspect not, but please confirm it).
>>>>
>>>No problem to call it twice IIRC
>>
>> Sorry - that's wrong advice.
> Taht was not advice but answer you and Eugene didn't understand what I
> mean , I too stand that it's not good practice to close already , but that
> practically closed without any problems if it done correctly...
>>
>> The socket handle may very well be reused before the first closesocket()
>> has
>> even returned to your application, and you'll be closing a socket that
>> you
>> don't actually own.
>>
> No, you can close only your sockets ( or created by your or received
> through WSADuplicateSocket() ) otherwise error will returned
>
>> You have to be extraordinarily careful to make sure that closesocket() is
>> only
>> ever called on sockets that you own, and that you know are not going to
>> be
>> referenced again by your code (except as a completely new socket).
>>
> Handles you have is your own only and not system wide , that's why if you
> want to use that socket in different process that have to be used with
> WSADuplicateSocket() and closesocket for other-then-your-process will
> return WSAENOTSOCK error.
>
>> Socket handle reuse has typically been _very_ aggressive in Windows; I
>> haven't
>> tested it in years, but it's fairly easy to test - just keep opening and
>> closing sockets more or less randomly, and look to see how quickly a new
>> socket will get created using the old handle.
>>
>>>> 3. are the socket values/handles "reused" immediately or is there a
>>>> (configurable ?) "freeze" time ?
>>>>
>>>That happen by default after 2 MSL which is 240 sec by default
>>
>> No - you are confusing sockets and socket handles. Sockets remain in
>> TIME_WAIT state after they are closed; socket handles do not. The socket
>> handle for the socket that remains in TIME_WAIT state is _not_ maintained
>> by
>> the stack after closesocket() has been called - closesocket specifically
>> disassociates the socket handle from the socket (and does not necessarily
>> close the socket).
>
> No, I checked that on Windows CE , where socket handle's receive
> sequential numbers in the process ( 0,1,2... ) and handle was not reused
> up to socket was open ( really for 32bit system it have 4 billion numbers
> before reuse :) ) , that will be funny to check that on 64 bit system (
> AFAIK really not exist yet such :) )
>
> Arkady
>
>>
>> Alun.
>> ~~~~
>>
>> [Please don't email posters, if a Usenet response is appropriate.]
>> --
>> Texas Imperial Software | Find us at http://www.wftpd.com or email
>> 23921 57th Ave SE | alun@wftpd.com.
>> Washington WA 98072-8661 | WFTPD, WFTPD Pro are Windows FTP servers.
>> Fax/Voice +1(425)807-1787 | Try our NEW client software, WFTPD Explorer.
>
>
date: Sun, 25 Dec 2005 11:10:07 +0200
author: John Smith
Re: Winsock API socket value "reuse" ?
In article , "Arkady Frenkel"
wrote:
>
>"Alun Jones" <alun@texis.invalid> wrote in message
>news:RqKdnfmEl5KyzzHeRVn-pw@comcast.com...
>> In article <#Cdm34fBGHA.272@TK2MSFTNGP09.phx.gbl>, "Arkady Frenkel"
>> wrote:
>>>> - My question is this - if thread (B) calls "closesocket" TWICE with the
>>>> same value, then this raises some questions:
>>>>
>>>> 1. is the second call "safe" - i.e., assuming there was no
>>>> multi-threading (see question 2) is the second call to "closesocket"
>>>> same
>>>> as a NOOP...(I suspect not, but please confirm it).
>>>>
>>>No problem to call it twice IIRC
>>
>> Sorry - that's wrong advice.
>Taht was not advice but answer you and Eugene didn't understand what I mean
>, I too stand that it's not good practice to close already , but that
>practically closed without any problems if it done correctly...
No, calling closesocket() on the same handle twice _is_ a problem. Saying "no
problem to call it twice" is bad advice.
If you call closesocket() twice on the same handle, the best you can hope for
is that the second call will signal WSAENOTSOCK, because that will indicate
you didn't accidentally close a socket that is open by you or some other
thread in your application (and, as you note, even single-threaded
applications have other threads that open sockets).
If you don't get WSAENOTSOCK, that would mean that you closed another socket,
one that isn't your responsibility to close, that was opened by some other
portion of your process.
>> The socket handle may very well be reused before the first closesocket()
>> has
>> even returned to your application, and you'll be closing a socket that you
>> don't actually own.
>>
>No, you can close only your sockets ( or created by your or received through
>WSADuplicateSocket() ) otherwise error will returned
"Ownership" in this sense refers to segments of code, and as you point out,
those segments must be in the same thread, unless you've created a child
process and made it inherit the sockets, or you've used WSADuplicateSocket to
pass the handle to another process.
This brings up the point that closesocket() needs to be called twice if you've
handed off the socket to another process. Here's the procedure:
1. open socket
2. Duplicate socket by inheritance or WSADuplicateSocket.
3. Close socket in process that opened it.
4. Close socket in process that possesses the duplicate.
(3 and 4 can occur in the other order, and there may be other access to the
socket in between).
>> You have to be extraordinarily careful to make sure that closesocket() is
>> only
>> ever called on sockets that you own, and that you know are not going to be
>> referenced again by your code (except as a completely new socket).
>>
>Handles you have is your own only and not system wide , that's why if you
>want to use that socket in different process that have to be used with
>WSADuplicateSocket() and closesocket for other-then-your-process will return
>WSAENOTSOCK error.
But handles that are for your process may be for sockets that your code did
not create. Remember how gethostbyname, etc will cause the Winsock stack to
create a secondary thread for DNS resolution? Well, that thread owns a
socket, and the socket handle is in your process's usual space for socket
handles - that means you can close the socket accidentally and kill your DNS
access.
>> Socket handle reuse has typically been _very_ aggressive in Windows; I
>> haven't
>> tested it in years, but it's fairly easy to test - just keep opening and
>> closing sockets more or less randomly, and look to see how quickly a new
>> socket will get created using the old handle.
...
>No, I checked that on Windows CE , where socket handle's receive sequential
>numbers in the process ( 0,1,2... ) and handle was not reused up to socket
>was open ( really for 32bit system it have 4 billion numbers before reuse
>:) ) , that will be funny to check that on 64 bit system ( AFAIK really not
>exist yet such :) )
Socket handles don't get reused while the socket is open, that would be
ludicrous. Maybe I'm not understanding you.
Once you call closesocket(), the socket handle may be assigned to the next
socket that comes out of socket() or accept().
Here's an example piece of code:
#include <winsock.h>
#include <stdio.h>
void main()
{
WSADATA wsad;
WSAStartup(0x101,&wsad);
printf("Handle values: \n");
for (int i=0;i<20;i++)
{
SOCKET s1=socket(AF_INET,SOCK_STREAM,0);
printf(" %3d",(int)s1);
closesocket(s1);
}
}
Now, as you can see, this simply opens a socket, prints its handle, then
closes the socket; it does this in a loop 20 times. If the socket handle
reuse is aggressive, we would expect to see the same socket handle value
occurring a few times. Here's the output I get on XP:
Handle values:
1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956
1956 1956 1956 1956 1956
Wow, that's what I'd call aggressive - in the femto-seconds between the
closesocket() call and the socket() call, the handle has already been reused.
So, if I have code that looks like this:
SOCKET s1,s2;
...
s1=socket(...);
...
closesocket(s1); // Close the first socket
s2=socket(...);
closesocket(s1); // Close the first socket again - oops.
...
Then I have closed the first socket _and_ the second socket.
My second socket is now dead, even if the second socket was created by another
thread in my process, even if the second socket was not created by my code or
at my request.
It is always wrong to close a handle to anything more than the handle has been
opened. Just as it is always wrong to doubly de-reference any resource.
Alun.
~~~~
[Please don't email posters, if a Usenet response is appropriate.]
--
Texas Imperial Software | Find us at http://www.wftpd.com or email
23921 57th Ave SE | alun@wftpd.com.
Washington WA 98072-8661 | WFTPD, WFTPD Pro are Windows FTP servers.
Fax/Voice +1(425)807-1787 | Try our NEW client software, WFTPD Explorer.
date: Mon, 26 Dec 2005 06:04:14 GMT
author: lid (Alun Jones)
|
|