probelm with recv() on a tcp connection

Posted by michael on Stack Overflow See other posts from Stack Overflow or by michael
Published on 2011-03-06T15:44:59Z Indexed on 2011/03/06 16:10 UTC
Read the original article Hit count: 161

Filed under:
|
|
|
|

Hi, I am simulating TCP communication on windows in C I have sender and a receiver communicating. sender sends packets of specific size to receiver. receiver gets them and send an ACK for each packet it received back to the sender. If the sender didn't get a specific packet (they are numbered in a header inside the packet) it sends the packet again to the receiver. Here is the getPacket function on the receiver side:

//get the next packet from the socket. set the packetSize to -1
//if it's the first packet.
//return: total bytes read
// return: 0 if socket has shutdown on sender side, -1 error, else number of bytes received
int getPakcet(char *chunkBuff,int packetSize,SOCKET AcceptSocket){
int totalChunkLen = 0;
int bytesRecv=-1;
bool firstTime=false;
if (packetSize==-1) {
    packetSize=MAX_PACKET_LENGTH;
    firstTime=true;
}

int needToGet=packetSize;
        do
                    {
                        char* recvBuff;
                        recvBuff = (char*)calloc(needToGet,sizeof(char));
                        if(recvBuff == NULL){
                            fprintf(stderr,"Memory allocation problem\n");
                            return -1;
                        }

                        bytesRecv = recv(AcceptSocket, recvBuff, needToGet, 0);
                        if (bytesRecv == SOCKET_ERROR){
                            fprintf(stderr,"recv() error %ld.\n", WSAGetLastError());
                            totalChunkLen=-1;
                            return -1;
                        }
                        if (bytesRecv == 0){
                            fprintf(stderr,"recv(): socket has shutdown on sender side");
                            return 0;
                        }
                        else if(bytesRecv > 0)
                        {                           
                            memcpy(chunkBuff + totalChunkLen,recvBuff,bytesRecv); 
                            totalChunkLen+=bytesRecv;
                        }
                        needToGet-=bytesRecv;
                    } 
                    while ((totalChunkLen < packetSize) && (!firstTime));
return totalChunkLen;


}

i use firstTime because for the first time the receiver doesn't know the normal package size that the sender is going to send to it, so i use a MAX_PACKET_LENGTH to get a package and then set the normal package size to the num of bytes i have received

my problem is the last package. it's size is less than the package size so lets say last package size is 2 and the normal package size is 4. so recv() gets two bytes, continues to the while condition, then totalChunkLen < packetSize because 2<4 so it iterates the loop again and the gets stuck in recv() because it's blocking because the sender has nothing to send.

on the sender side i can't close the connection because i didn't ACK back, so it's kind of a deadlock. receiver is stuck because it's waiting for more packages but sender has nothing to send.

i don't want to use a timeout for recv() or to insert a special character to the package header to mark that it is the last one

what can i do ?

thanks

© Stack Overflow or respective owner

Related posts about c++

Related posts about Windows