recv() stops when there's exactly 508 bytes left.

Started by
16 comments, last by hplus0603 13 years, 2 months ago
Hello you!

As the topic states, my recv() call keeps stopping when there is 508 bytes left to read. I'm trying to send a file, and it's all going good untill we hit the magical 508 bar.

Sending


void
sendFile(char *fileName)
{
struct fileInfo info;
FILE *file;
long fileSize;
char *buffer, temp[512];
int left, sent, total;

/* Open the file */
file = fopen(fileName, "rb");
if (file == NULL)
logThis("sendFile", "Out of memory while opening file.");

/* Obtain file zie */
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
rewind(file);

/* Allocate memory for the buffer */
buffer = (char *)malloc(sizeof(char) * fileSize);
if (buffer == NULL) {
logThis("sendFile", "Out of memory.");
exit(99);
}

/* Copy file contents over to our buffer */
fread(buffer, 1, fileSize, file);
logThis("sendFile", "Buffer contains: %s", buffer);

/* Send the file name first, and then our size */
info.size = fileSize;
snprintf(info.name, 32, "%s", fileName);
logThis("sendFile", "Name: %s, size: %d", info.name, info.size);
sendCommand(NET_FILEINFO, (char *)&info);

/* Start sending file */
total = 0;
left = fileSize;
logThis("sendFile", "Ready to send: %d bytes", left);
while (total < fileSize) {
sent = send(serverSocket, buffer + total, left, 0);


if (sent == 0) {
logThis("handle", "Connection closed during transfer");
break;
} else if (sent < 0) {
logThis("handle", "Error during tansfer!");
break;
} else {
total += sent;
left -= sent;
logThis("sendFile", "Sent: %d bytes. %d bytes left", sent, left);
}
}
logThis("sendFile", "Done sending. Sent: %d vs %d", total, fileSize);
}


And where i get the file


void
*handle(void *argument)
{
struct fileClient *client;
struct fileInfo *info;
char buffer[512], *fileBuffer;
FILE *file;
int total, read, ret;

/* Get the client */
client = (struct fileClient *)argument;

/* Ready for files, send OK message */
sendCommand(client->clientSocket, NET_OK, " ");

/* Expect file name and then size */
recvCommand(client->clientSocket, NET_FILEINFO, buffer);
info = (struct fileInfo *)buffer;
logThis("handle", "File name: %s file size: %d", info->name, info->size);

/* Allocate memory for the file */
fileBuffer = (char *)malloc(info->size);

/* Keep recieving data and copying it into the file buffer untill done */
total = 0;
read = info->size;
while (read > 0) {
ret = recv(client->clientSocket, (fileBuffer + total), read, 0);

if (ret == 0) {
logThis("handle", "Connection closed during transfer");
break;
} else if (ret < 0) {
logThis("handle", "Error during tansfer!");
break;
} else {
total += ret;
read -= ret;
logThis("handle", "Read: %d bytes. %d bytes left", ret, read);
}
}

/* Create the file on disk and save it */
file = fopen(info->name, "wb");
fwrite(fileBuffer, 1, info->size, file);
fclose(file);
pthread_exit(NULL);
}


I should note that sometimes, the file manages to be downloaded completly.
Omg, zombie! Zomgbie.
Advertisement
Your while(total < left) loop will be wrong when you both increase total and decrease left, as they will meet on the middle. You probably want while(total < filesize).
You're correct. Not sure what i missed in my calculations, but indeed, it will skip when they meet on the middle.

But i still have the exact same problem. My send() function reports that all data have been sent, but when the recv() functions hits 508 bytes, it just stops :(
Omg, zombie! Zomgbie.
Change your client loop like this, and see if you get some new output.

ret = recv(client->clientSocket, (fileBuffer + total), read, 0);
if(ret == 0)
// connection closed
else if(ret < 0)
// error
else {
total += ret;
read -= ret;
}


Also, print out (or check with the debugger) the first 50 bytes or something of the file, to make sure they are equal on the server and client-side, so you don't miss any data at the start.
Nothing new sadly.

When there is 508 bytes left to read, recv just stops receiving. It will block the flow of the program (I'm using blocking sockets) untill the poor server shuts down, and therefore disconnects the client. There are no errors, and ret == 0 does not happend untill i actually shutdown the server. Feeling like i've gotten something very wrong, somewhere!

The output

...

[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 96348 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 79964 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 63580 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 47196 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 30812 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 14428 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 13920 bytes. 508 bytes left
... Nothing happens here, untill i disconnect the server. Then it says:

[backupTool][2011-02-24][14:59:40][handle]: Connection closed during transfer
Omg, zombie! Zomgbie.
Did you compare the data you actually receive with the data you send on the server?
Try printing out the last 10 bytes sent from the server and the last 10 bytes received on the client, to make sure your data isn't just offset 508 bytes, and the last byte you received is actually supposed to be at the end of the file. For example open your file in a hex editor and type 'test123' at the end or something, and make sure it is actually sent and not received.
Tried that out now. All bytes are identical untill we hit the 508 mark, where i cannot compare anymore :(
Omg, zombie! Zomgbie.
Does your server flush/close the socket after all bytes are sent?
Right now it does. It waits for 1 minut after sending, and then closes the socket. When i'm done with this, i'm not planning on closing the socket after the transfer. There is more data to be sent afterwards :)
Omg, zombie! Zomgbie.
It should work. Try flushing the socket immediately after finishing anyway. You might also try disabling Nagle's algorithm, but I don't think that should be causing a problem as your clinet should be acknowledging every read().

Can you post a minimal client that demonstrates this behaviour? What about trying to readthe data byte by byte into the buffer? It does seem that your code has an issue when the "data left" drops below the size 16384.

This topic is closed to new replies.

Advertisement