Asynchronous TCP/IP

S

Silby

Having finally got a working asynchronous server up (sends and recieves data
fine) i get stuck again.
I'm not quite sure how i can safely disconnect the client. It doesnt really
matter how initiates the disconnect, both sides should be able to do it.
The problem lies in the callback function for reading data, more
specifically, at this point:
bytesRead = handler.EndReceive(AR)

bytesread is an int, handler a socket and AR and IAsyncResult.

When disconnecting it still seems to want to read the termination signals,
but by then the socket is already gone.
Now i currently solve it in a rather crappy manner :) I catch the error, set
bytesread to a negative value and make sure that when bytesread is negative,
all the remaining code does not get run.

Can someone explain how i could catch a termination signal and cleanly solve
it ?
 
T

Tom Shelton

Having finally got a working asynchronous server up (sends and recieves data
fine) i get stuck again.
I'm not quite sure how i can safely disconnect the client. It doesnt really
matter how initiates the disconnect, both sides should be able to do it.
The problem lies in the callback function for reading data, more
specifically, at this point:
bytesRead = handler.EndReceive(AR)

bytesread is an int, handler a socket and AR and IAsyncResult.

When disconnecting it still seems to want to read the termination signals,
but by then the socket is already gone.
Now i currently solve it in a rather crappy manner :) I catch the error, set
bytesread to a negative value and make sure that when bytesread is negative,
all the remaining code does not get run.

Can someone explain how i could catch a termination signal and cleanly solve
it ?

While I'm not exactly sure what your asking... EndReceive will return 0
when the remote endpoint has shutdown and all data in the buffer has
been recieved.
 
S

Silby

Tom Shelton said:
While I'm not exactly sure what your asking... EndReceive will return 0
when the remote endpoint has shutdown and all data in the buffer has
been recieved.

Basicly, when one of both sockets closes (Socket.Shutdown, Socket.Close) it
will still run the callback function to read data and ofcourse crash then,
because there it still tries to do handler.EndReceive. Catching the error
shows:
Cannot access a disposed object named "System.net.sockets.socket".
So the socket was already terminated by the time it got into the read
callback.

What i want to know is :
is this normal behaviour and am i supposed to handle it with try/catch
(doubtful :)
Is there something like BeginDisconnect that i can use to handle this ?

Hope this clears it up a bit
 
S

Silby

Tom Shelton
MVP [Visual Basic]

Basicly, when one of both sockets closes (Socket.Shutdown, Socket.Close) it
will still run the callback function to read data and ofcourse crash then,
because there it still tries to do handler.EndReceive. Catching the error
shows:
Cannot access a disposed object named "System.net.sockets.socket".
So the socket was already terminated by the time it got into the read
callback.

What i want to know is :
is this normal behaviour and am i supposed to handle it with try/catch
(doubtful :)
Is there something like BeginDisconnect that i can use to handle this ?

Hope this clears it up a bit

And another update ...

I came to the conclusion i could do the following:

ReadCallBack
numread = socket.EndReceive
if (numread > 0) then
buffer = whatweread
if instr(buffer, "QUIT") then
close_connection
** Do NOT do Beginreceive here ! **
else
socket.BeginReceive
End if
End if
End Sub

this solves the problem of the read call back being called with a terminated
socket.
But now the sockets dont close !!
client side goes into FIN_WAIT2 and server side goes into CLOSE_WAIT.

Closing the socket goes as follows:

close_connection
socket.Shutdown(socketshutdown.both)
socket.close
end sub
 
S

Silby

Silby said:
Tom Shelton
MVP [Visual Basic]

Basicly, when one of both sockets closes (Socket.Shutdown, Socket.Close) it
will still run the callback function to read data and ofcourse crash then,
because there it still tries to do handler.EndReceive. Catching the error
shows:
Cannot access a disposed object named "System.net.sockets.socket".
So the socket was already terminated by the time it got into the read
callback.

What i want to know is :
is this normal behaviour and am i supposed to handle it with try/catch
(doubtful :)
Is there something like BeginDisconnect that i can use to handle
this
?

Hope this clears it up a bit

And another update ...

I came to the conclusion i could do the following:

ReadCallBack
numread = socket.EndReceive
if (numread > 0) then
buffer = whatweread
if instr(buffer, "QUIT") then
close_connection
** Do NOT do Beginreceive here ! **
else
socket.BeginReceive
End if
End if
End Sub

this solves the problem of the read call back being called with a terminated
socket.
But now the sockets dont close !!
client side goes into FIN_WAIT2 and server side goes into CLOSE_WAIT.

Closing the socket goes as follows:

close_connection
socket.Shutdown(socketshutdown.both)
socket.close
end sub

And i should learn not to post before trying all my options ...
Seems TcpClient isnt all that, and thats why the socket didnt close down
cleanly. Fixed now, problems solved.

Thanks for taking the time to help.
 
T

Tom Shelton

Silby said:
Tom Shelton
MVP [Visual Basic]

Basicly, when one of both sockets closes (Socket.Shutdown, Socket.Close) it
will still run the callback function to read data and ofcourse crash then,
because there it still tries to do handler.EndReceive. Catching the error
shows:
Cannot access a disposed object named "System.net.sockets.socket".
So the socket was already terminated by the time it got into the read
callback.

What i want to know is :
is this normal behaviour and am i supposed to handle it with try/catch
(doubtful :)
Is there something like BeginDisconnect that i can use to handle
this
?

Hope this clears it up a bit

And another update ...

I came to the conclusion i could do the following:

ReadCallBack
numread = socket.EndReceive
if (numread > 0) then
buffer = whatweread
if instr(buffer, "QUIT") then
close_connection
** Do NOT do Beginreceive here ! **
else
socket.BeginReceive
End if
End if
End Sub

this solves the problem of the read call back being called with a terminated
socket.
But now the sockets dont close !!
client side goes into FIN_WAIT2 and server side goes into CLOSE_WAIT.

Closing the socket goes as follows:

close_connection
socket.Shutdown(socketshutdown.both)
socket.close
end sub

And i should learn not to post before trying all my options ...
Seems TcpClient isnt all that, and thats why the socket didnt close down
cleanly. Fixed now, problems solved.

Thanks for taking the time to help.

LOL! I'm glad you solved the issues - but I'm not exactly sure what I
did to help :)
 
C

cybrshdw

I am currently Working On MudProject This is the way that we close our
connections

Public Sub CloseClientConenction()
IsConnected = False
Dim NWStream As NetworkStream =Client.GetStream
NWStream.Flush()
NWStream.Close()
Client.Close()
RaiseEvent ClientClose(Me)
End Sub

Also There is a Really Well Done MultiThreaded TCPserver Class File at
www.voidRealms.com this is what we based our TCP server off of also
there is a updated Version at
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=1885
&lngWId=10

Its worth a Check out It does have a bug with The Above Code that is now
fixed if you replace with the above example
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top