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 / Languages / C# / October 2007

Tip: Looking for answers? Try searching our database.

How to continue using a Socket after a timeout?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
carl.rosenberger@gmail.com - 21 Oct 2007 16:16 GMT
Hi,

I am trying to get the following behaviour for my Socket connection:

(1) Attempt a blocked read for a defined amount of time.
(2) If a timeout occurs, because no data has been sent to the socket,
throw an exception.
(3) Catch the exception and either go back to (1) or quit reading,
depending on a variety of (user defined) factors.

To implement the above I use:

socket.SetSocketOption(
  SocketOptionLevel.Socket,
  SocketOptionName.ReceiveTimeout,
  timeout);

Everything works as expected until the first timeout occurs. When
try to read again after the first timeout, the next exception occurs
immediately, without respecting the timeout setting.

I get a System.IO.IOException with the following Message:
"Unable to read data from the transport connection: A non-blocking
socket operation could not be completed immediately."

Even after I send data to the socket and successfully read data, the
behaviour of throwing an exception immediately when no data is
avaialble does not go away and I never get the socket back to a
state where it obeys the timeout in the read operation.

What am I missing?

Is there some kind of reset button that I can push on a timeout?
carl.rosenberger@gmail.com - 21 Oct 2007 18:17 GMT
carl.rosenber...@gmail.com wrote:
> I am trying to get the following behaviour for my Socket connection:
>
[quoted text clipped - 3 lines]
> (3) Catch the exception and either go back to (1) or quit reading,
> depending on a variety of (user defined) factors.

Following up, here is a simple code sampe to reproduce the issue:

class Program
{

   static int TIMEOUT = 1500;

   Socket _serverSocket;

   Socket _server;

   Socket _client;

   NetworkStream _inputStream;

   static void Main()
   {
       new Program().Run();
   }

   public void Run()
   {
       OpenServerSocket();
       ConnectClient();
       AcceptServer();
       ConfigureTimeout();
       OpenInputStream();

       CheckTimeoutOnRead();
       CheckTimeoutOnRead();

       CloseAll();
   }

   private void CheckTimeoutOnRead()
   {
       int start = Environment.TickCount;
       int stop = 0;
       try
       {
           _inputStream.ReadByte();
       }
       catch (Exception ex)
       {
           stop = Environment.TickCount;
           Console.WriteLine(ex);
       }

       int duration = stop - start;

       Console.WriteLine("Expected timeout: " + TIMEOUT);
       Console.WriteLine("Actual timeout: " + duration);
   }

   void OpenServerSocket()
   {
       _serverSocket = NewSocket();
       _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
       _serverSocket.Listen(42);
   }

   void ConnectClient()
   {
       _client = NewSocket();
       _client.Connect(new IPEndPoint(Resolve("localhost"), Port()));
   }

   void AcceptServer()
   {
       _server = _serverSocket.Accept();
   }

   void ConfigureTimeout()
   {
       _server.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, TIMEOUT);
       _server.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.SendTimeout, TIMEOUT);
   }

   void OpenInputStream()
   {
       _inputStream = new NetworkStream(_server);
   }

   void CloseAll()
   {
       _client.Close();
       _server.Close();
       _serverSocket.Close();
   }

   int Port()
   {
       return ((IPEndPoint)_serverSocket.LocalEndPoint).Port;
   }

   Socket NewSocket()
   {
       return new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
   }

   IPAddress Resolve(string hostName)
   {
       IPHostEntry found = Dns.Resolve(hostName);
       foreach (IPAddress address in found.AddressList)
       {
           if (address.AddressFamily == AddressFamily.InterNetwork)
           {
               return address;
           }
       }
       throw new Exception();
   }
}
Peter Duniho - 21 Oct 2007 18:25 GMT
> [...]
> Even after I send data to the socket and successfully read data, the
[quoted text clipped - 5 lines]
>
> Is there some kind of reset button that I can push on a timeout?

No.  It's unfortunate that the .NET docs aren't more clear about this;
the Winsock docs do a better job.  From the docs for SO_RCVTIMEO and
SO_SNDTIMEO (http://msdn2.microsoft.com/en-us/library/ms740476.aspx):

    If a send or receive operation times out on a socket,
    the socket state is indeterminate, and should not be used;
    TCP sockets in this state have a potential for data loss,
    since the operation could be canceled at the same moment
    the operation was to be completed.

Don't use the ReceiveTimeout property if you want to be able to use the
socket after the timeout occurs.

I think you will be happier if you adjust your thinking to not treat
your "timeout" as an exception.  That is, you don't really have an
exception...you have a time-based monitoring situation in which you want
to perform some specific, configurable action after a fixed amount of time.

So, instead of using the timeout property of the socket, just set up
some sort of timer somewhere that executes code after a fixed amount of
time.  Only if the actual behavior you want is to cancel the i/o on the
socket would you then close the socket when the timer goes off.

Pete

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.