开发者

"Connection Reset by Peer" if server calls close() immediately after write()

I have a AF_INET/SOCK_STREAM server written in C running on Android/Linux which looks more ore less like this:

...
for (;;) {
    client = accept(...);
    read(client, &message, sizeof(message));
    response = process(&message);
    write(client, response, sizeof(*response));
    close(client);
}

As far as I know, the call to close should not terminate the connection to the client immediately, but 开发者_运维百科it apparently does: The client reports "Connection Reset by Peer" before it has had a chance to read the server's response.

If I insert a delay between write() and close() the client can read the response as expected.

I got a hint that it might have to do with the SO_LINGER option, but I checked it's value and both members of struct linger (l_onoff, l_linger) have a value of zero.

Any ideas?


Stevens describes a configuration in which this can happen, but it depends on the client sending more data after the server has called close() (after the client should “know” that the connection is being closed). UNP 2nd ed s5.12.

Try tcpdumping the conversation to find out what’s really going on. If there's any possibility that a “clever” gateway (e.g. NAT) is between the two endpoints, tcpdump both ends and look for discrepancies.


Connection gets reset when you call close() on connection with data being sent. Specially for this case the sequence of shutdown() with SHUT_WR flag and then blocking read() is used.

Shutting down the writing end of the socket sends FIN and returns immediately, and the said read() blocks and returns 0 as soon as your peer replies with FIN in due turn. Basically, this is what you need in place of the delay between write() and close() you are talking about.

You do not need do anything with linger options in this case, leave it all to default.


SO_LINGER should be set (i.e. set to 1 not 0) if you want queued data to be sent before a close is effected.

SO_LINGER Lingers on a close() if data is present. This option controls the action taken when unsent messages queue on a socket and close() is performed. If SO_LINGER is set, the system shall block the calling thread during close() until it can transmit the data or until the time expires. If SO_LINGER is not specified, and close() is issued, the system handles the call in a way that allows the calling thread to continue as quickly as possible. This option takes a linger structure, as defined in the header, to specify the state of the option and linger interval.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜