Reputation: 323
The following code continues to receive data in the same file("/tmp/frame"), when the real purpose is to receive in separate files. It seems that the server starts to receive a file and does not close, continuing to receive data of the following files in the same.
(the comments in the code solve the problem, but delay the transfer of files)
Sender:
screenshot ptr_screen;
CHAR Block[4096], buffer[512];
int BytesRead, iResult;
for (;;) {
memset(Block, 0, sizeof(Block));
memset(buffer, 0, sizeof(buffer));
ptr_screen.Start();
FILE *fp = fopen("screen.jpg", "rb");
if (!fp) { break; }
fseek(fp, 0, SEEK_END);
int32_t file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
iResult = send(socket_, (char*)&file_size, sizeof(file_size), 0);
if (iResult == SOCKET_ERROR) { fclose(fp); break; }
while (file_size > 0) {
BytesRead = fread(Block, 1, sizeof(Block), fp);
if (BytesRead <= 0) { break; }
iResult = send(socket_, Block, BytesRead, 0);
if (iResult != BytesRead) { break; }
file_size -= BytesRead;
}
fflush(fp);
fclose(fp);
//if (recv_to(socket_, buffer, sizeof(buffer), 0, 5000) <= 0)
//break;
}
Receiver:
int iResult;
char Block[512];
int32_t file_size;
for(;;) {
FILE* fp = fopen("/tmp/frame", "wb");
if(!fp) { break; }
memset(Block, 0, sizeof(Block));
iResult = recv_to((char*)&file_size, sizeof(file_size), 10);
if(iResult <= 0 ) { break; }
while(file_size > 0) {
iResult = recv_to(Block, sizeof(Block), 10);
if(iResult <= 0) { break; }
if(fwrite(Block, 1, iResult, fp) != (unsigned)iResult) { return; }
file_size -= iResult;
}
fclose(fp);
system("mv /tmp/frame /tmp/stream.jpg");
//send(socket_, "OK", strlen("OK"), 0); // response
}
Upvotes: 0
Views: 55
Reputation: 52561
TCP is a stream protocol. The receiver wouldn't generally receive data broken down into the same chunks as how the sender sent them - you'll get chunks broken down essentially arbitrarily.
In particular, when the sender sends the last piece of a file, then immediately sends the size and the first chunk from the new file, it's entirely possible that the receiver will receive the last chunk, the size, and the part of the first chunk of next file, all rolled together in one block. file_size
will go negative, which will get you out of the inner loop this one time. But then, you are going to read into file_size
some random data from the middle of the next file. It probably just happens to form a very large integer, that's why your inner loop doesn't seem to exit anymore.
In the inner loop read max(sizeof(Block), file_size)
bytes, so you don't go over the file boundary.
Upvotes: 2