views:

176

answers:

4

I have client/server program in C, through which I am transferring files to the client from server.

But the client is waiting for recv even after receiving the last byte of the file. Client is terminating only if I kill it or server is killed by me. But server has to be in a loop as it to has to entertain the request of other clients.

I am using fork() in the server to entertain the request of each client. I'm exiting from the child process after the request of the client has been entertained, but the client is terminating only when the whole server program is killed.

Why doesn't the client terminate when the server's child exits?

You can see server code here and client code here.

A: 

You should be calling something like: shutdown(s, SD_SEND); closesocket(s);

on the server after sending the file to close the socket.

Steven
A: 

This is a bit hard, more detail would be nice. Are you using TCP/IP? Since you talk about file transfers, I'll assume it's TCP.

If you're terminating the process on the server side that owns the socket connected to the client, that should lead to the connection terminating. The client's recv() call should then finish and return -1 (or 0, not 100% sure). Failing that, look into explicitly closing the socket in the main server process (not sure how you've set up your socket ownership).

unwind
A: 

There are two ways of reading sockets...

  1. receiving byte by byte with recv(), but problem is if your content contains -1 in middle of your data then it will indicate end of file.

  2. Another way is to read buffer from stream, and this method will return the number of bytes read from stream, and if that returns 0 that means its end of stream.

Akash Kava
-1 for the completely bogus point about -1 in the middle of the file
Alnitak
One function call per byte truely sucks! you need to do better than that.
Blank Xavier
+3  A: 

You should make sure that you call shutdown(s, SHUT_WR) followed by close(s) in the server process once all of the data has been sent.

The call to shutdown() tells the TCP layer that there's no more data to be sent.

TBH, I'm not quite sure why calling close() on its own doesn't also achieve that.

EDIT - I've figured that out now - it's because at that point in your code the parent also still has the socket open so it doesn't get torn down by the kernel. If after the fork() you add some extra logic:

if (p > 0) {
    close(connected);
}

then your code works without a call to shutdown().

If you're using the code I sent in my answer to your question from yesterday then the client will get a bytes_received count of zero and then terminate its loop.

Alnitak
thanks for your reply!are'nt the file shared by both parent and child ,once i have close connected by the child i think should work.by the way as u said once the client recieved zero bytes it will come out of it's loop and will finally exit .but it is not happening ,child is waiting for something even after recieving all.i hv also put printf in the loop but it is not showing any thing untill server is killed!
mawia
no, the file is shared, but the file descriptors are separate. If you close it in the child it still remains open in the parent. Because the file is still open the server never sends the zero-length indicator for end-of-stream. I added the code above to your server program and then everything worked fine.
Alnitak