By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,952 Members | 1,725 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,952 IT Pros & Developers. It's quick & easy.

Detecting Remote Client Socket Close in BeginReceive

P: n/a
In the following code snippet, the thread successfully makes it to the
line where it waits for data to be received. Then the client closes the
connection. The thread wakes up and returns from the WaitOne()
operation. No exception is thrown when it loops and executes
BeginReceive() again. The WaitOne() operation returns immediately.
Thus, there's an endless loop.

How does one detect that the remote client has closed the connection in
this situation?
//
// Started as a new thread to handle data received on an
// open socket.
//
private void ReceiveDataEventLoop(Socket clientSocket) {
while (true) {
try {
ClientState clientState = new ClientState(clientSocket);
IAsyncResult result = clientSocket.BeginReceive(
clientState.Buffer,
0,
clientState.Buffer.Length,
SocketFlags.None,
new AsyncCallback(this.ReceiveDataCallback),
clientState);

// Wait for the EndReceive before issuing a new BeginReceive
// When the remote client closes the connection, this starts
// to return immediately. How to identify that remote client
// closed connection?
result.AsyncWaitHandle.WaitOne();

} catch (SocketException) {
removeSocket(clientSocket);
break;
} catch (Exception) {
removeSocket(clientSocket);
break;
}
}
}

Oct 26 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
OK. I have a workaround:

Instead of using "result.AsyncWaitHandle.WaitOne()", I created a
ManualResetEvent and passed it to the BeginReceive delegate. When the
BeginReceive delegate starts, it gets the number of bytes when it calls
EndReceive. If 0, the BeginReceive delegate closes the socket. After
processing the data, the ManualResetEvent is set. Thus, when the
ReceiveDataEventLoop wakes up, it will try to access a disposed object
when it calls BeginReceive and then exit from its event loop.

O.B. wrote:
In the following code snippet, the thread successfully makes it to the
line where it waits for data to be received. Then the client closes the
connection. The thread wakes up and returns from the WaitOne()
operation. No exception is thrown when it loops and executes
BeginReceive() again. The WaitOne() operation returns immediately.
Thus, there's an endless loop.

How does one detect that the remote client has closed the connection in
this situation?
//
// Started as a new thread to handle data received on an
// open socket.
//
private void ReceiveDataEventLoop(Socket clientSocket) {
while (true) {
try {
ClientState clientState = new ClientState(clientSocket);
IAsyncResult result = clientSocket.BeginReceive(
clientState.Buffer,
0,
clientState.Buffer.Length,
SocketFlags.None,
new AsyncCallback(this.ReceiveDataCallback),
clientState);

// Wait for the EndReceive before issuing a new BeginReceive
// When the remote client closes the connection, this starts
// to return immediately. How to identify that remote client
// closed connection?
result.AsyncWaitHandle.WaitOne();

} catch (SocketException) {
removeSocket(clientSocket);
break;
} catch (Exception) {
removeSocket(clientSocket);
break;
}
}
}
Oct 26 '06 #2

P: n/a
"O.B." <fu******@bellsouth.netwrote in message
news:12*************@corp.supernews.com...
[...]
How does one detect that the remote client has closed the connection in
this situation?
As you have found, the receive function returns a bytes received value of 0
when the connection is closed.

However, your problem has less to do with that, than that you have created
an infinite loop that tries to receive over and over again without any means
of checking the socket for validity.

It seems to me that if you insist on this design, then the BeginReceive
method *ought* to throw an exception once your socket has been closed. That
is, after receiving 0 for the return value for EndReceive, you ought to be
able to just close the socket there, causing an exception here and allowing
the loop to exit.

However, in that case you don't have a direct means of knowing whether the
connection was closed normally or abnormally. IMHO, it would be better to
not have this design in the first place, requeuing the receive *only* when
you know you have successfully completed the previous receive (that is, in
the same code where you call EndReceive).

Pete
Oct 26 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.