0

I'm working with socket programming and am currently attempting to transfer a 1MB file through 16KB at a time. The data does initially transfer 16KB at a time; however, my ifstream reaches EOF prematurely which makes it so the file transfer is incomplete.

int main() {

int SIZE = 16000;
char file_buffer[SIZE];
int i = 0;

ifstream my_file("1MB", ios::in | ios::binary);
if (!my_file) {
    cout << "No such file";
} else {
io_service io_service;
// socket creation
ip::tcp::socket client_socket(io_service);

client_socket
    .connect(
        tcp::endpoint(
            address::from_string("127.0.0.1"),
            9999));


while(!my_file.eof()) {
    char ch;

        my_file >> ch;
        if(my_file.eof())
        {
            cout << "File Buffer: " << file_buffer << endl;
            cout << "ERROR: EOF DETECTED" << endl;
            break;
        }
        else if (i == SIZE)
        {
            sendData(client_socket, file_buffer);
            memset(file_buffer, 0, sizeof file_buffer);
            i = 0;
        } else
        {
            file_buffer[i] = ch;
            i++;
        }
    }

}
my_file.close();
return 0;

}

Towermoni
  • 27
  • 5
  • If the file size isn't an exact multiple of `SIZE`, what do you do with what you have in the `file_buffer`? It looks like you just drop that. – Ted Lyngmo May 04 '21 at 20:43
  • small nitpick: `char` is not `unsigned char`. Since you are dealing with binary data, using `uint8_t` would be better and more explicit. – Casey May 04 '21 at 20:48
  • Also, `while(!my_file.eof())` is incorrect. Use `unsigned char ch; while(my_file >> ch)`. – Casey May 04 '21 at 20:53

1 Answers1

0

It looks like you discard the data at the end of the file if the file size isn't an exact multiple of SIZE.

Also, even if the file size is an exact multiple of SIZE you'll be reading the last character and then eof() will not return true. Not until you've tried reading the next character will eof() return true, and that will trigger your error message, ERROR: EOF DETECTED.

More on that here:
Why is iostream::eof() inside a loop condition (i.e. while (!stream.eof())) considered wrong?

An alternative approach:

unsigned i = 0;

while(my_file >> file_buffer[i]) { // loop for as long as extracting succeeds
    if(++i == SIZE) {
        sendData(client_socket, file_buffer, i);       // add a size parameter
        // memset(file_buffer, 0, sizeof file_buffer); // why waste the time?
        i = 0;
    }
}

if(i) sendData(client_socket, file_buffer, i); // send the last part in the buffer
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108