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: 227
        
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