Reputation: 393
I am writing a network C program where a client sends a block of data to a server, and I want to make sure that all data have been read by the server before I close the socket from the client side. I thought of sending a special 'ok' character back from the server to the client, but I am thinking that if something wrong happens during the execution of the server program and the server closes the pipe from his side (e.g. read system call fails), the client is going to wait on a read system call for something that will never come. Any idea about how I can solve this?
thanks, Nikos
Upvotes: 1
Views: 259
Reputation: 73379
It seems like there are four possible outcomes for your client:
The first three can be handled in a straightforward manner on the client. To handle the fourth, you'd need to implement a timeout on the client side -- but then you run the risk of timing out prematurely, when really the server was just slow to respond, rather than actually broken. Probably the best thing is to make the timeout quite generous (e.g. 30 seconds?), and also making sure that your server is reliable and doesn't hang. :)
Upvotes: 0
Reputation: 46052
There's no need to worry about when to close the socket on your client's side. As long as the data has been written to the socket, you can close it any time after that. @cnicutar provides a good explanation of this in his answer.
As far as special acknowledgement characters from your server back to the client, you shouldn't have to worry about that with TCP. However, you might want to modify your data block so that it includes a header indicating how much data there is. For example, the first 4 bytes of the data block could be a length field indicating how many more bytes there are. The server could read the first 4 bytes and then know how many more bytes to read. TCP communications typically has something like this.
Upvotes: 0
Reputation: 2043
alternating bit protocol is a way to solve that. there are different ways to implement that.
When A sends a message, it resends it continuously, with the same sequence number, until it receives an acknowledgment from B that contains the same sequence number. When that happens, A complements (flips) the sequence number and starts transmitting the next message.
Upvotes: 0
Reputation: 182774
I want to make sure that all data have been read by the server b*efore I close the socket from the client side*.
If you are using TCP consider this: once you send the data, even if you close the socket / exit the program, the TCP stack will continue to do its best to send it.
Once you send
/ write
the data, it's gone from your hands. It's copied in a kernel buffer and sent some time later. Behind the scenes (somewhere deep in netinet
) the connection is not closeduntil all sent data has been acknowledged / the connection is terminated due to other reasons.
Upvotes: 1
Reputation: 1136
Implement a timeout in the client. Wait some configurable / reasonable amount of time on a response from the server. If that time period elapses, act accordingly.
Upvotes: 0
Reputation: 1651
The implementation you propose sounds fine to me - if something wrong happens, that's an exceptional case - to catch that, you'll need to use a timeout on your read call.
Upvotes: 0