probelm with recv() on a tcp connection
- by michael
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