Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. TcpClient - Detecting closed connections

TcpClient - Detecting closed connections

Scheduled Pinned Locked Moved C#
helpquestionsysadmin
11 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Grimes
    wrote on last edited by
    #1

    Hello there. I am currently writing a server and client application. I have code that can handle it when client users close their connection, however detecting when the connection has closed due to an error is a completely different story. What is the best way to do this? I had a look at the forum and found similar questions. One of these propose that I use the Linger and Time Out properties of TCPClient to determine whether the connection is still open. What I read from MSDN about these properties are that they determine the time that write/read operations may wait to complete. To me this does not seem like a good way to test the connection, because shortening these times might close connections when in actual fact the remote connection hasn't disconnected but is merely very busy. Am I wrong? Is my understanding of lingering and time outs correct? Another solution proposes that I use polling to determine whether the connections are open. This is actually what I am currently doing. My server has a thread that every once in a while sends a small piece of test data to every connection. I then try and catch the IOException exceptions that are thrown when I send data to a connection that closed at the client side. This seems to work for the most part, however, it does not throw immediately when I send the test data, it seems to throw randomly on the 2nd or 3rd set of test data. Only after it has thrown does the server's TCPCLient.Connected property change to false. How can I get the connection to immediately throw the exception? Could there be a better way to fix this and to see if the connection has closed? Any Help is appreciated Thanks!

    KOM UIT DAAAAA!!!

    B J 2 Replies Last reply
    0
    • G Grimes

      Hello there. I am currently writing a server and client application. I have code that can handle it when client users close their connection, however detecting when the connection has closed due to an error is a completely different story. What is the best way to do this? I had a look at the forum and found similar questions. One of these propose that I use the Linger and Time Out properties of TCPClient to determine whether the connection is still open. What I read from MSDN about these properties are that they determine the time that write/read operations may wait to complete. To me this does not seem like a good way to test the connection, because shortening these times might close connections when in actual fact the remote connection hasn't disconnected but is merely very busy. Am I wrong? Is my understanding of lingering and time outs correct? Another solution proposes that I use polling to determine whether the connections are open. This is actually what I am currently doing. My server has a thread that every once in a while sends a small piece of test data to every connection. I then try and catch the IOException exceptions that are thrown when I send data to a connection that closed at the client side. This seems to work for the most part, however, it does not throw immediately when I send the test data, it seems to throw randomly on the 2nd or 3rd set of test data. Only after it has thrown does the server's TCPCLient.Connected property change to false. How can I get the connection to immediately throw the exception? Could there be a better way to fix this and to see if the connection has closed? Any Help is appreciated Thanks!

      KOM UIT DAAAAA!!!

      B Offline
      B Offline
      BobJanova
      wrote on last edited by
      #2

      To understand why this is a problem, look at how a TCP connection works. It is kept alive by, essentially, ping and acknowledgement packets, and a connection is 'dropped' if no acknowledgement packets are received. (It can also be actively closed, which is different, and which closes the Socket object and gives you a 0 byte read on the input stream.) That means that if a connection is lost, the time taken for the OS to notice is dependent on how long it's prepared to wait and how often it pings the connection. I think, if you aren't sending any data, the connection is never checked. That's why sending data into the connection provokes the exception – it makes the OS look at the connection and say 'oh, nothing has been received for a minute, it must be closed'. Sometimes it won't fail because the overall timeout hasn't expired and it hasn't done a 'ping test' so your first data packet is what triggers the 'waiting for acknowledgement' and then the connection is marked as dropped after the ack timeout (a few seconds, I think). These issues all come about because TCP is essentially emulating a connected, stream transfer subsystem on top of a packet-based, fire and forget one (IP), and working out when a receiver has gone away in that situation is not always immediately possible. In my sockets library I catch the exceptions (SocketException, and also ObjectDisposedException which can happen if .Net closes and disposes of the socket without telling you about it) and treat that as a disconnection.

      G 2 Replies Last reply
      0
      • B BobJanova

        To understand why this is a problem, look at how a TCP connection works. It is kept alive by, essentially, ping and acknowledgement packets, and a connection is 'dropped' if no acknowledgement packets are received. (It can also be actively closed, which is different, and which closes the Socket object and gives you a 0 byte read on the input stream.) That means that if a connection is lost, the time taken for the OS to notice is dependent on how long it's prepared to wait and how often it pings the connection. I think, if you aren't sending any data, the connection is never checked. That's why sending data into the connection provokes the exception – it makes the OS look at the connection and say 'oh, nothing has been received for a minute, it must be closed'. Sometimes it won't fail because the overall timeout hasn't expired and it hasn't done a 'ping test' so your first data packet is what triggers the 'waiting for acknowledgement' and then the connection is marked as dropped after the ack timeout (a few seconds, I think). These issues all come about because TCP is essentially emulating a connected, stream transfer subsystem on top of a packet-based, fire and forget one (IP), and working out when a receiver has gone away in that situation is not always immediately possible. In my sockets library I catch the exceptions (SocketException, and also ObjectDisposedException which can happen if .Net closes and disposes of the socket without telling you about it) and treat that as a disconnection.

        G Offline
        G Offline
        Grimes
        wrote on last edited by
        #3

        Hi thanks for the reply. You say your library catches SocketException and also ObjectDisposedException and treat that as an indication that the connection has closed. When does these exceptions get thrown? When you send data? Say for example I am connected to a remote computer. If his connection closes abruptly, under which conditions will these exceptions get thrown on my machine? Would .Net eventually close\dispose my connection if the connection was closed on the remote machine? I was not aware that it worked that way, maybe I misunderstood what you meant.

        KOM UIT DAAAAA!!!

        B 1 Reply Last reply
        0
        • B BobJanova

          To understand why this is a problem, look at how a TCP connection works. It is kept alive by, essentially, ping and acknowledgement packets, and a connection is 'dropped' if no acknowledgement packets are received. (It can also be actively closed, which is different, and which closes the Socket object and gives you a 0 byte read on the input stream.) That means that if a connection is lost, the time taken for the OS to notice is dependent on how long it's prepared to wait and how often it pings the connection. I think, if you aren't sending any data, the connection is never checked. That's why sending data into the connection provokes the exception – it makes the OS look at the connection and say 'oh, nothing has been received for a minute, it must be closed'. Sometimes it won't fail because the overall timeout hasn't expired and it hasn't done a 'ping test' so your first data packet is what triggers the 'waiting for acknowledgement' and then the connection is marked as dropped after the ack timeout (a few seconds, I think). These issues all come about because TCP is essentially emulating a connected, stream transfer subsystem on top of a packet-based, fire and forget one (IP), and working out when a receiver has gone away in that situation is not always immediately possible. In my sockets library I catch the exceptions (SocketException, and also ObjectDisposedException which can happen if .Net closes and disposes of the socket without telling you about it) and treat that as a disconnection.

          G Offline
          G Offline
          Grimes
          wrote on last edited by
          #4

          I had a look at my initial post. I did not clearly state the nature of the problem. The problem is that I am having trouble detecting when the remote connection closes on it's side of the connection. It seems like your answer is on detecting when the connection closed on my side of the connection, or it seems that way. If there was any confusion, I apologize since I was not more clear on the nature of the problem in the initial post... Thanks for the replies though. :)

          KOM UIT DAAAAA!!!

          E 1 Reply Last reply
          0
          • G Grimes

            Hi thanks for the reply. You say your library catches SocketException and also ObjectDisposedException and treat that as an indication that the connection has closed. When does these exceptions get thrown? When you send data? Say for example I am connected to a remote computer. If his connection closes abruptly, under which conditions will these exceptions get thrown on my machine? Would .Net eventually close\dispose my connection if the connection was closed on the remote machine? I was not aware that it worked that way, maybe I misunderstood what you meant.

            KOM UIT DAAAAA!!!

            B Offline
            B Offline
            BobJanova
            wrote on last edited by
            #5

            If the remote client actively closes the connection, you will get a 0 byte result from Read, most of the time. This should be your normal closure condition. If the connection is lost, either because the network drops out or because the remote client dies or otherwise closes the connection without doing so actively, you will, in general, not be notified. Yes, typically exceptions are thrown when you try to write to the socket. I think if you wait long enough the OS will time out an idle connection, but that timeout is quite long (minutes, at least), and in some cases the timeout can be infinite i.e. you would never be told that the connection died.

            G 1 Reply Last reply
            0
            • B BobJanova

              If the remote client actively closes the connection, you will get a 0 byte result from Read, most of the time. This should be your normal closure condition. If the connection is lost, either because the network drops out or because the remote client dies or otherwise closes the connection without doing so actively, you will, in general, not be notified. Yes, typically exceptions are thrown when you try to write to the socket. I think if you wait long enough the OS will time out an idle connection, but that timeout is quite long (minutes, at least), and in some cases the timeout can be infinite i.e. you would never be told that the connection died.

              G Offline
              G Offline
              Grimes
              wrote on last edited by
              #6

              Thanks for the reply. It seems to me then that the way I am currently doing is probably the best way to detect the closed connection due to errors. I would then just have to accept that I need to wait for the connection to time out. I will add a check to check what the result is of an read, to see if the remote client actively closed. Thanks for the help.

              KOM UIT DAAAAA!!!

              1 Reply Last reply
              0
              • G Grimes

                I had a look at my initial post. I did not clearly state the nature of the problem. The problem is that I am having trouble detecting when the remote connection closes on it's side of the connection. It seems like your answer is on detecting when the connection closed on my side of the connection, or it seems that way. If there was any confusion, I apologize since I was not more clear on the nature of the problem in the initial post... Thanks for the replies though. :)

                KOM UIT DAAAAA!!!

                E Offline
                E Offline
                elgaabeb
                wrote on last edited by
                #7

                Hi, take a look at keep alive signals, they could be usefull to you : http://msdn.microsoft.com/en-us/library/ms819735.aspx[^] best regards!

                G B 2 Replies Last reply
                0
                • E elgaabeb

                  Hi, take a look at keep alive signals, they could be usefull to you : http://msdn.microsoft.com/en-us/library/ms819735.aspx[^] best regards!

                  G Offline
                  G Offline
                  Grimes
                  wrote on last edited by
                  #8

                  Yes this will be VERY useful! Thanks!

                  KOM UIT DAAAAA!!!

                  1 Reply Last reply
                  0
                  • E elgaabeb

                    Hi, take a look at keep alive signals, they could be usefull to you : http://msdn.microsoft.com/en-us/library/ms819735.aspx[^] best regards!

                    B Offline
                    B Offline
                    BobJanova
                    wrote on last edited by
                    #9

                    Good catch. For a dedicated server machine that could be handy.

                    1 Reply Last reply
                    0
                    • G Grimes

                      Hello there. I am currently writing a server and client application. I have code that can handle it when client users close their connection, however detecting when the connection has closed due to an error is a completely different story. What is the best way to do this? I had a look at the forum and found similar questions. One of these propose that I use the Linger and Time Out properties of TCPClient to determine whether the connection is still open. What I read from MSDN about these properties are that they determine the time that write/read operations may wait to complete. To me this does not seem like a good way to test the connection, because shortening these times might close connections when in actual fact the remote connection hasn't disconnected but is merely very busy. Am I wrong? Is my understanding of lingering and time outs correct? Another solution proposes that I use polling to determine whether the connections are open. This is actually what I am currently doing. My server has a thread that every once in a while sends a small piece of test data to every connection. I then try and catch the IOException exceptions that are thrown when I send data to a connection that closed at the client side. This seems to work for the most part, however, it does not throw immediately when I send the test data, it seems to throw randomly on the 2nd or 3rd set of test data. Only after it has thrown does the server's TCPCLient.Connected property change to false. How can I get the connection to immediately throw the exception? Could there be a better way to fix this and to see if the connection has closed? Any Help is appreciated Thanks!

                      KOM UIT DAAAAA!!!

                      J Offline
                      J Offline
                      jschell
                      wrote on last edited by
                      #10

                      TCP the protocol (not TCPClient) for the most part does not do what you are asking. And although Keep Alive is part of the protocol in general it is not going to be useful. Generally it won't even work unless you control the entire network infrastructure for all the components. And working doesn't mean it is useful. If a connection pool is in use, then the properties of the connection pool dictate how idle connections are handled. If a connection pool is not in use then idle connections will not be closed (excluding a close from the client.) A pool will close sockets that are in an error state or closed but that only happens after it is detected. Excluding a pool being configured to send a keep alive (probably not the same as the TCP Keep Alive) it relies on the user functionality to detect such errors. Pool keep alives can be considered to exist only in database pools as determining other types of keep alives depend on the client. This has nothing to do with language/API either. But briefly looking at the docs for TCPClient I see nothing that suggests a pool is in use. In general the only way to tell if a socket is still good is to send something and wait for it to indicate it went. This is not 100% but is generally sufficient especially if a reply is expected. Again this is how TCP works. Additionally, and this impacts the point of Keep Alive (TCP protocol) the point is - why do you think this matters? What exactly are you gaining? For example lets say you have a data center with two 24x7 servers that talk to each other. From that the following scenarios exist. - 99% of the time there is no problem. - 0.99% of the time there is a socket closure caused by a scheduled bounce of one of the servers. - 0.01% of the time the socket fails because of a 'network' failure which could include someone kicking out the power cord of one of the servers. Now for the last case is can occur at ANY time. So the fact that a socket was 'alive' a minute ago doesn't help you any when you actually use it because it can fail when you use it. So the only way do deal with is either your code that USES the socket is written to deal with retries or you accept some infrequent processing errors (and other businesses process deal with it.) Note that the second case can occur at any time as well. Conversely the other 99.99% of the time you are now sending keep alives (not necessarily TCP) around the system to no purpose. Why no purpose? Because the system is up. So they don't do anythin

                      G 1 Reply Last reply
                      0
                      • J jschell

                        TCP the protocol (not TCPClient) for the most part does not do what you are asking. And although Keep Alive is part of the protocol in general it is not going to be useful. Generally it won't even work unless you control the entire network infrastructure for all the components. And working doesn't mean it is useful. If a connection pool is in use, then the properties of the connection pool dictate how idle connections are handled. If a connection pool is not in use then idle connections will not be closed (excluding a close from the client.) A pool will close sockets that are in an error state or closed but that only happens after it is detected. Excluding a pool being configured to send a keep alive (probably not the same as the TCP Keep Alive) it relies on the user functionality to detect such errors. Pool keep alives can be considered to exist only in database pools as determining other types of keep alives depend on the client. This has nothing to do with language/API either. But briefly looking at the docs for TCPClient I see nothing that suggests a pool is in use. In general the only way to tell if a socket is still good is to send something and wait for it to indicate it went. This is not 100% but is generally sufficient especially if a reply is expected. Again this is how TCP works. Additionally, and this impacts the point of Keep Alive (TCP protocol) the point is - why do you think this matters? What exactly are you gaining? For example lets say you have a data center with two 24x7 servers that talk to each other. From that the following scenarios exist. - 99% of the time there is no problem. - 0.99% of the time there is a socket closure caused by a scheduled bounce of one of the servers. - 0.01% of the time the socket fails because of a 'network' failure which could include someone kicking out the power cord of one of the servers. Now for the last case is can occur at ANY time. So the fact that a socket was 'alive' a minute ago doesn't help you any when you actually use it because it can fail when you use it. So the only way do deal with is either your code that USES the socket is written to deal with retries or you accept some infrequent processing errors (and other businesses process deal with it.) Note that the second case can occur at any time as well. Conversely the other 99.99% of the time you are now sending keep alives (not necessarily TCP) around the system to no purpose. Why no purpose? Because the system is up. So they don't do anythin

                        G Offline
                        G Offline
                        Grimes
                        wrote on last edited by
                        #11

                        You make a very good point.

                        KOM UIT DAAAAA!!!

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups