Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / June 2006

Tip: Looking for answers? Try searching our database.

How do you close TCP connections?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Lucvdv - 12 Jun 2006 16:01 GMT
I'm using a TcpClient object:

- Open:

   m_Connection = New Net.Sockets.TcpClient
   m_Connection.Connect(IPAddress.Parse(IP), 2101)
   m_Stream = m_Connection.GetStream

- Close:

   If m_Connection IsNot Nothing Then
       If m_Stream IsNot Nothing Then
           m_Stream.Close()
           m_Stream.Dispose()
           m_Stream = Nothing
       End If
       m_Connection.Close()
       m_Connection = Nothing
   End If

However, it seems that this isn't enough to really close and dispose of the
connection (the Dispose member of TcpClient is not available, but I could
make up from the docs that it's implicitly called by TcpClient.Close).

When I examine the connections in TcpView (www.sysinternals.com), I see
each connection I close "jump" from my application to the SYSTEM process,
and remain there in TIME_WAIT state for a while before it really
disappears.

The length of time they remain is the same for all connections, so I think
it's a time-out, which must be about 5 minutes after they are closed.

Stopping the application doesn't make any difference: the connections still
remain, listed under SYSTEM process, until they've time out one by one.

The app creates one new connection per minute and closes it after sending 1
packet and receiving the anwer, which is as good as immediately; the
connections disappear from TcpView with 1 minute intervals as well.

Yet when I use a protocol analyzer, I see the twin FIN-ACK/ACK sequences
fully pass over the network, so the connection is really closed.

Then why is TcpView still listing them, even after the application has
stopped?

The only thing that's not really expected in the dump (with my app, haven't
checked with another) is that the final FIN-ACK coming from the remote side
has the PSH flag set (for which I can see no reason).

Would an additional flag in combination with FIN make the packet invalid?

Below is an Ethereal dump of the process of closing a connection (after
which TcpView showed it remaining in existence for 5 minutes longer).

10.1.1.11 is the local side, 10.1.1.101 is a network-attached device (not a
PC).

[TCP Checksum incorrect] remarks on the outgoing packets can be ignored
according to Ethereal FAQ q5.14: adapter supporting checksum offloading,
the checksum will be added by the network adapter, this hasn't been done
yet when the packets are captured.

> No.     Time        Source                Destination           Protocol Info
>      14 0.682681    10.1.1.11             10.1.1.101            TCP      2173 > 2101 [FIN, ACK] Seq=9 Ack=85 Win=17436 [TCP CHECKSUM INCORRECT] Len=0
>
> Frame 14 (54 bytes on wire, 54 bytes captured)
> Ethernet II, Src: 10.1.1.11 (00:0a:5e:54:8a:6e), Dst: 10.1.1.101 (00:40:9d:24:49:2a)
> Internet Protocol, Src: 10.1.1.11 (10.1.1.11), Dst: 10.1.1.101 (10.1.1.101)
> Transmission Control Protocol, Src Port: 2173 (2173), Dst Port: 2101 (2101), Seq: 9, Ack: 85, Len: 0
>     Source port: 2173 (2173)
>     Destination port: 2101 (2101)
>     Sequence number: 9    (relative sequence number)
>     Acknowledgement number: 85    (relative ack number)
>     Header length: 20 bytes
>     Flags: 0x0011 (FIN, ACK)
>         0... .... = Congestion Window Reduced (CWR): Not set
>         .0.. .... = ECN-Echo: Not set
>         ..0. .... = Urgent: Not set
>         ...1 .... = Acknowledgment: Set
>         .... 0... = Push: Not set
>         .... .0.. = Reset: Not set
>         .... ..0. = Syn: Not set
>         .... ...1 = Fin: Set
>     Window size: 17436
>     Checksum: 0x168c [incorrect, should be 0xac6f]
>     SEQ/ACK analysis
>         This is an ACK to the segment in frame: 13
>         The RTT to ACK the segment was: 0.021875000 seconds
>
> No.     Time        Source                Destination           Protocol Info
>      15 0.684649    10.1.1.101            10.1.1.11             TCP      [TCP ZeroWindow] 2101 > 2173 [ACK] Seq=85 Ack=10 Win=0 Len=0
>
> Frame 15 (60 bytes on wire, 60 bytes captured)
> Ethernet II, Src: 10.1.1.101 (00:40:9d:24:49:2a), Dst: 10.1.1.11 (00:0a:5e:54:8a:6e)
> Internet Protocol, Src: 10.1.1.101 (10.1.1.101), Dst: 10.1.1.11 (10.1.1.11)
> Transmission Control Protocol, Src Port: 2101 (2101), Dst Port: 2173 (2173), Seq: 85, Ack: 10, Len: 0
>     Source port: 2101 (2101)
>     Destination port: 2173 (2173)
>     Sequence number: 85    (relative sequence number)
>     Acknowledgement number: 10    (relative ack number)
>     Header length: 20 bytes
>     Flags: 0x0010 (ACK)
>         0... .... = Congestion Window Reduced (CWR): Not set
>         .0.. .... = ECN-Echo: Not set
>         ..0. .... = Urgent: Not set
>         ...1 .... = Acknowledgment: Set
>         .... 0... = Push: Not set
>         .... .0.. = Reset: Not set
>         .... ..0. = Syn: Not set
>         .... ...0 = Fin: Not set
>     Window size: 0
>     Checksum: 0xf08b [correct]
>     SEQ/ACK analysis
>         This is an ACK to the segment in frame: 14
>         The RTT to ACK the segment was: 0.001968000 seconds
>         TCP Analysis Flags
>             This is a ZeroWindow segment
>
> No.     Time        Source                Destination           Protocol Info
>      16 0.705081    10.1.1.101            10.1.1.11             TCP      2101 > 2173 [FIN, PSH, ACK] Seq=85 Ack=10 Win=0 Len=0
>
> Frame 16 (60 bytes on wire, 60 bytes captured)
> Ethernet II, Src: 10.1.1.101 (00:40:9d:24:49:2a), Dst: 10.1.1.11 (00:0a:5e:54:8a:6e)
> Internet Protocol, Src: 10.1.1.101 (10.1.1.101), Dst: 10.1.1.11 (10.1.1.11)
> Transmission Control Protocol, Src Port: 2101 (2101), Dst Port: 2173 (2173), Seq: 85, Ack: 10, Len: 0
>     Source port: 2101 (2101)
>     Destination port: 2173 (2173)
>     Sequence number: 85    (relative sequence number)
>     Acknowledgement number: 10    (relative ack number)
>     Header length: 20 bytes
>     Flags: 0x0019 (FIN, PSH, ACK)
>         0... .... = Congestion Window Reduced (CWR): Not set
>         .0.. .... = ECN-Echo: Not set
>         ..0. .... = Urgent: Not set
>         ...1 .... = Acknowledgment: Set
>         .... 1... = Push: Set
>         .... .0.. = Reset: Not set
>         .... ..0. = Syn: Not set
>         .... ...1 = Fin: Set
>     Window size: 0
>     Checksum: 0xf082 [correct]
>
> No.     Time        Source                Destination           Protocol Info
>      17 0.705103    10.1.1.11             10.1.1.101            TCP      [TCP Window Full] 2173 > 2101 [ACK] Seq=10 Ack=86 Win=17436 [TCP CHECKSUM INCORRECT] Len=0
>
> Frame 17 (54 bytes on wire, 54 bytes captured)
> Ethernet II, Src: 10.1.1.11 (00:0a:5e:54:8a:6e), Dst: 10.1.1.101 (00:40:9d:24:49:2a)
> Internet Protocol, Src: 10.1.1.11 (10.1.1.11), Dst: 10.1.1.101 (10.1.1.101)
> Transmission Control Protocol, Src Port: 2173 (2173), Dst Port: 2101 (2101), Seq: 10, Ack: 86, Len: 0
>     Source port: 2173 (2173)
>     Destination port: 2101 (2101)
>     Sequence number: 10    (relative sequence number)
>     Acknowledgement number: 86    (relative ack number)
>     Header length: 20 bytes
>     Flags: 0x0010 (ACK)
>         0... .... = Congestion Window Reduced (CWR): Not set
>         .0.. .... = ECN-Echo: Not set
>         ..0. .... = Urgent: Not set
>         ...1 .... = Acknowledgment: Set
>         .... 0... = Push: Not set
>         .... .0.. = Reset: Not set
>         .... ..0. = Syn: Not set
>         .... ...0 = Fin: Not set
>     Window size: 17436
>     Checksum: 0x168c [incorrect, should be 0xac6e]
>     SEQ/ACK analysis
>         This is an ACK to the segment in frame: 16
>         The RTT to ACK the segment was: 0.000022000 seconds
>         TCP Analysis Flags
>             The transmission window is now completely full
Vadym Stetsyak - 12 Jun 2006 17:42 GMT
Hello, Lucvdv!

<skip>

L> When I examine the connections in TcpView (www.sysinternals.com), I see
L> each connection I close "jump" from my application to the SYSTEM
L> process, and remain there in TIME_WAIT state for a while before it
L> really disappears.

TIME_WAIT is a normal situation. You can workaround it using SocketOptionName.ReuseAddress.

for more details look at ( http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4669.aspx )

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
Lucvdv - 13 Jun 2006 07:48 GMT
> Hello, Lucvdv!
>
[quoted text clipped - 8 lines]
>
> for more details look at ( http://www.technewsgroups.net/group/microsoft.public.dotnet.general/topic4669.aspx )

Thanks, I see it now.

I thought it wasn't normal because other applications (such as Internet
Explorer) don't show this behavior.

So my real problem must be due to something else (as I already suspected,
actually - and this isn't meant as a new question, BTW).

I'm connecting to network-attached devices (not PC-based) that support only
one connection at a time.  It happens from time to time that they miss when
a connection is being closed, and start behaving as if there's still one in
use when there isn't.

Their behavior with a second connection is quite distinct, so I don't have
much doubt that the frozen devices simply think theyre still connected.
Besides, I can still telnet to another port and after a soft reboot it
starts working again.
Lucvdv - 13 Jun 2006 14:38 GMT
> TIME_WAIT is a normal situation. You can workaround it using SocketOptionName.ReuseAddress.

Just some comments after I looked it up in the RFC878 and did some more
searches.

The link you provided mentions a one minute delay, but actuelly it's
longer.

The delay can be set in the registry, at
HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\Services\Tcpip\Parameters.

DWORD value TcpTimedWaitDelay, legal values 30 to 300 (seconds).

The default is 240 seconds, so I wasn't far off with my 5 minutes.

Now I also understand why some programs do it and some don't: it's only
necessary for that socket that sends the first FIN/ACK, i.e. the side that
takes the initiative of closing the connection.

In most application layer protocols (mail, FTP etc.), the client sends a
QUIT command to the server, upon which the server closes the connection -
meaning the socket in TIME_WAIT will be found at the server.

Interesting: the HTTP protocol (Web browsers) is an exception to that, and
Internet Explorer is an exception within that category.

When I visited a website in Firefox and then closed the browser window, the
connection went through a TIME_WAIT phase.  When I did the same in Internet
Explorer, it did *not* TIME_WAIT, which could very well mean that IE
doesn't close its connections in a clean RFC-compliant way.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.