views:

258

answers:

2

I have a client/server program (Windows, winsock2) which communicates over TCP. The client connects and sends data to server (using send) in 8K at a time. The server just reads data (using recv).

No special settings done on sockets.

Problem: When some network error occurs during the communication (e.g. cable pulled out), receiver do not get data successfully sent by that time. To simplify, Client sent 80K data in 10 calls to send. (all sends are successful). 11th send failed because of some network issue. No more data sent after this.

Problem is that at receiver, not all 80K data is received. It is always less than 80K.

I expect as sender as successfully sent 80K, TCP will guarantee that much data is delivered to destination TCP (data may not be received by application yet, but its in destination TCP buffers).

Am I missing anything?

Thanks

Edit:

Sample code

Server/receiver

/* create socket */
/* listen */
/* accept connection */
char recvbuf[8192];
do {

    iResult = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0);
    if (iResult > 0) {
        total += iResult;
        printf("Total bytes received: %d\n", total);
    }
    else if (iResult == 0) {
        printf("Connection is closing...\n");
        break;
    }
    else  {
        printf("recv failed: %d\n", WSAGetLastError());
        break;
    }

} while (iResult > 0);


Client/sender :

/* create socket */
/* connect to server */
char sendbuf[8192];

do {
    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, sizeof(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        break;
    }
    total += iResult;
    printf("Total bytes Sent: %ld\n", total);
} while(iResult > 0);
//wait before cleaning up
getc(stdin);
A: 

Are you calling send and recv in a loop? They do not guarantee that they send or receive all the data or buffer that you provide.

http://stackoverflow.com/questions/1837444

Also you should really post some code, otherwise we can only guess.

Tim Sylvester
Yes send/recv are called in a loop. But I assume that if send() is successful, that data should reach destination TCP. (and subsequently to application through 1 or more recv()Will post code in short time.
rohan
+1  A: 

Your assumption is flawed.

send() returning successfully just means that the data has been accepted to send by your kernel - it could still be sitting in your send queues.

If you want to know if the data has reached the other end, you must be application-level acknowledgements in.

(See also this question)

caf
Wouldn't acks be recursive.When receiver app sends ACK for received data, how will it be sure that all bytes of ACK packet are delivered.
rohan
That is true, and is an unsolvable problem in the general case. What this means is that your sender application only knows that the receiver has seen *at least* what it has recieved ACKs for - it must retransmit anything else. Your sender must then be prepared to detect and discard data that was retransmitted unnecessarily.
caf