Есть достаточно большой двоичный файл (ок. 1мб), он передается по сети для записи в файл на компьютере-приемнике (под windows). Но вот при запуске просто из проводника часть файла (именно конец файла) теряется. При запуске из cmd все работает как надо.
фрагмент кода:
//s - сокет
int n;
int l = 1195520;
char b[l];
puts("Getting...");
n = recv(s, b, l, 0);
if(n < 0) return 1;
puts("Got file");
n = send(s, "got the file!
", 14, 0);
if(n < 0) return 1;
FILE * f;
f = fopen("file1", "wb");
fwrite(&b, sizeof(b), 1, f);
fclose(f);
close(s);
puts("Wrote");
Ответ
Согласно man recv(2) (важная часть выделена мной):
If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking ... The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.
Для удобства нужна функция, принимающая из сокета все данные до конца (раз нам известен точный размер). Что-нибудь вроде такого (код не проверялся):
int recv_all(int socket, void *data, size_t size)
{
size_t received_total = 0;
ssize_t received_now = 0;
size_t bytes_left = size;
while(1) {
received_now = recv(socket, data + received_total, bytes_left, 0);
if (received_now < 0) {
// как-нибудь обработать ошибку
break;
}
received_total += received_now;
bytes_left -= received_now;
}
return received_total;
}
Использовать так:
size_t received;
int data_size = 1195520;
char buffer[data_size];
size_t received = recv_all(sock, buffer, data_size);
if (received < data_size) {
return 1;
}
FILE *f = fopen("file1", "wb");
...
Комментариев нет:
Отправить комментарий