2

as background I've got an embedded device that talks to a third party server over IP. The code in the third party server is unlikely to change. In a recent release I changed the ip disconnect function to call shutdown() before calling close() (previously it had just called close()). The embedded device disconnects without completing a comms session if certain interrupts occur. When this happens at the wrong point in a session the server is now producing a trace file which, for various reasons, is not acceptable to the customer. This only happens when shutdown is called, the server treats this as a failed to send error (and produces a trace file) while it treats the more abrupt close() as an other end disconnected error which doesn't need tracing.

So the obvious solution is to stop calling shutdown. Mr Barnes' answer in this question gives a good description of the two functions but, if you know that only one process is attached to a particular socket, is there any reason to use shutdown before a close?

Thanks, Patrick

Community
  • 1
  • 1
Patrick
  • 8,175
  • 7
  • 56
  • 72
  • What TCP stack are you using in the embedded device, and on the third party server? Not all TCP stacks have the same behaviour w.r.t. `shutdown` versus `close`. Also, are you setting the `SO_LINGER` option? – cjs Jun 18 '09 at 10:37
  • How do you identify the tcp stack? We do use SO_LINGER at our end. – Patrick Jun 18 '09 at 11:19
  • Start by letting us know which operating systems (or libraries) and versions are involved. – cjs Jun 18 '09 at 11:42

2 Answers2

4

It sounds to me as if "abrupt disconnection" has become part of your communications protocol, which is not a good thing. If the client is running for long after "certain interrupts occur" to decide whether or not to use shutdown() or close() and have that influence what the other end sees, it would be better to update your protocol to reliably deliver a "this session is aborted message."

That said, it's sounding as if this system (i.e., all of the interacting software) has gotten one bit (on the server) frozen badly enough that this sort of change is never going to happen. Probably what you want to do, rather than figuring out what the problem really is, is get a manager to sign off on a quick-and-dirty "just use close()" solution, after explaining to him that you're not really sure what other effects this could have, but things did seem to run ok that way before. (You haven't noticed any other bugs disappear since you made that change, have you?)

Deciding whether to get into a potentially expensive search to see what's really going on here, along with a potentially expensive (politically, if not financially) with some organization on the other end responsible for maintaining that software is really a management decision, not a technical one, though to be made properly it needs to be informed by the technical risks.

cjs
  • 25,752
  • 9
  • 89
  • 101
  • The client isn't running after interrupts occur, the only problem is that it is mis-interpreting a graceful shutdown as an error that needs tracing while is quite happy to accept a straight close. Either way it carries on working without problem just this side affect of the trace file... Good advice anyway, sometimes you just have to get things working how the customer wants it, Thanks. – Patrick Jun 18 '09 at 11:18
1

If you know that only one process is attached to a particular socket, is there any reason to use shutdown before a close?

No there isn't. Contrary to a lot of documentation out there. Close does the FIN/ACK close handshake if it hasn't been sent already.

EDIT: however that's not to say that shutdown doesn't have its uses: of course it does. If you want to stop sending, and want the receiver to know that, but want to keep receiving, that's what it's for. Another use is to almost solve the two-army problem and get synchronized closes: if you read EOS, send a shutdown and close; if you want to initiate the close, send a shutdown and read until EOS and then close. If your application protocol is correct the latter step shouldn't read any data, and the closes at both ends will have been fairly simultaneous.

user207421
  • 305,947
  • 44
  • 307
  • 483