Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: How do I terminate a socket before Socket.BeginReceive calls back?

I have a server that receives connection requests from clients. This server makes use of the asynchronous Socket.BeginReceive and Socket.EndReceive method. The code is pretty similar to the code found here.

In my case, after calling Socket.BeginReceive I need a timeout such that if the client hangs on to the connection but does not transmit any data at all for a fixed amount of time, I need to terminate the connection.

  • How do I go about terminating the connection in this scenario?
  • What is the best way of coding a timer?
like image 784
Lopper Avatar asked Dec 17 '09 12:12

Lopper


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

Just call the socket's Close() method. The callback method will run pretty quickly after that, you'll get an ObjectDisposedException when you call the EndReceive() method. Be prepared to catch that exception.

You probably don't want to block the thread that called BeginReceive, you'll need a System.Threading.Timer or System.Timers.Timer to detect the timeout. Its callback should call Close(). Beware of the inevitable race-condition this causes, the timer's callback will run if the response was received a microsecond before the timer expired. You'll close the socket, even though you got a good response. The next call to BeginReceive() will fail immediately.

like image 98
Hans Passant Avatar answered Sep 26 '22 13:09

Hans Passant


I know this thread is pretty old but I just encountered the same problem and I was not satisfied by the answer given here (or anywhere else by that matter).

A better solution to cancel a pending Socket.BeginReceive is to call Socket.Shutdown and not Socket.Close. This way the asynch handler is raised "normally", and a call to Socket.EndReceive returns 0 --> instead of throwing an ugly expected-exception. You should always have an

if (Socket.EndReceive() > 0) {
  //Do something
} else {
  //Socket has been shut down (either by you or the other end of the connection)
  //Now it's "safe" to call Socket.Close
  Socket.Close();
}

so you don't even need to adjust your asynch-callback to handle the manual cancellation.

like image 23
Xatian Avatar answered Sep 25 '22 13:09

Xatian