Page 1 of 1

CLOSE_WAIT Socket Problem

Posted: Thu Jul 11, 2013 12:51 am
by MyongKyun
Hi

I use createCallbackConnection() API, there are 2 TCP connection.

When RCF session timed out, it seems RCF framework could not gracefully shutdown socket.

client socket server socket
1st connection port 52545 ====> 50001
2nd connection port 52546 ====> 50001

When the session timed out, only 2nd TCP connection is closed (52546) at server side.

and 1st TCP connection & 2nd TCP connection are closed at client side.

So 1st TCP conecction(52545) is not closed at server side.

thus 1st socket is in the CLOSE_WAIT state at server side.

$ lsof -p 6228
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Server 6228 mang 9u IPv4 43863 0t0 TCP *:50001 (LISTEN)
Server 6228 mang 10u IPv4 46156 0t0 TCP localhost:50001->localhost:52545 (CLOSE_WAIT)


I attached the simple client/server source code to demonstrate this problem.
And also captured packets (wireshak).

I appreciated if you give me some help on this.

Thanks.
Mr.Lim

Re: CLOSE_WAIT Socket Problem

Posted: Sun Jul 14, 2013 12:38 pm
by jarl
The socket that ends up in CLOSE_WAIT is the socket controlled by this RcfClient<> object, on your server side:

Code: Select all

RcfClient<MyServiceCallback> callbackClient( gCallbackTransportPtr );
callbackClient.callback();
If you disconnect or destroy this RcfClient<>, the socket will be closed and the CLOSE_WAIT state will disappear. The reason that the socket is in CLOSE_WAIT, is that the callback server on the client has closed its side of the connection due to session timeout.

When you have a callback connection on your server side, your application code owns that connection, not the RcfServer. So the session timeouts you've set on the server:

Code: Select all

RCF::RcfServer server( RCF::TcpEndpoint("0.0.0.0", 50001) );
server.setSessionTimeoutMs(60*1000);
server.setSessionHarvestingIntervalMs(40*1000);
, will not have an effect on the callback connection, and you need to close it yourself, at a point in time which makes sense to your application.

Re: CLOSE_WAIT Socket Problem

Posted: Tue Jul 16, 2013 6:28 pm
by MyongKyun
Hi

Thanks for your support.

I added disconnect() of callback connection at session destroy function.

But CLOSE_WAIT is still exist when session timeout.

If I misundestand, let me know.

static void
onCallbackDisconnect(RCF::RcfSession &s)
{
std::cout << "disconnect" << std::endl;
RcfClient<MyServiceCallback> callbackClient( gCallbackTransportPtr );
callbackClient.getClientStub().disconnect();
s.setCloseSessionAfterWrite(true);
s.deleteSessionObject<std::string>();
}

Regards
Mr.LIM

Re: CLOSE_WAIT Socket Problem

Posted: Wed Jul 17, 2013 2:43 am
by jarl
The problem is that gCallbackTransportPtr is an auto_ptr<> and can thus only be used once. In main() you have already used gCallbackTransportPtr to construct a RcfClient<>, so after that, gCallbackTransportPtr is null, and the subsequent usage in the disconnection callback won't do anything.

I can see what you're trying to accomplish though. Have a read of this section in the user guide:

http://www.deltavsoft.com/doc/rcf_user_ ... ng_clients

, which describes how the server can create a map of callback connections, indexed by a client id. If you follow that example, then from your disconnection callback you can retrieve the client id of the connection that is being destroyed, look that up in the callback connection map, and delete the callback connection as well.

I hope that makes sense - otherwise I can elaborate.