Согласно this solution для отправки изображения через TCP. Поскольку код очень элегантный по сравнению с другими способами, и оба изображения и файла являются данными, я считаю, что мы можем использовать почти тот же код для отправки файла.C Ошибка передачи файлов сокета
Так что если я хочу отправить файл с клиента на сервер.
На клиента стороны
- размер на файл
- посыла размер файла // Вышеуказанные действия всегда будут работать, так что я буду показывать только код после того, как здесь
содержимого файла для чтения в буфер
char buf[size]; read(fs,buf,size);
отправьте буфер
int bytes = 0; for (uint i = 0;i<size;i+=bytes) { if ((bytes = send(sock,buf+i,size-i,0))<0) { fprintf(stderr,"Can not send file\n"); close(fd); return false; } fprintf(stderr,"bytes write = %d\n",bytes); }
А на сервере стороне
- размер RECV файла
RECV материал в буфер с размером от шага буфера 1
char buf[size]; int bytes=0; for (uint i = 0;i<size;i+=bytes) { if ((bytes = recv(sock,buf+i,size-i,0))<0) { fprintf(stderr,"Can not receive file\n"); return false; } fprintf(stderr,"bytes read = %d\n",bytes); }
записи к файлу
fwrite(buf,sizeof(char),size,fs);
Этот код будет компилироваться и работать.
Когда я отправляю двоичный файл cpp (24k) с клиента на сервер, так как клиент и сервер находятся на одном компьютере (OS X), этот двоичный файл будет получен и может быть выполнен.
Но если сервер пересылает файл обратно клиенту и клиент пересылает этот файл на сервер несколько раз, этот двоичный файл будет поврежден. Но количество отправленных байтов и количество полученных байтов совпадают, а размер файла по-прежнему равен 24k.
Мне интересно, что здесь происходит.
Является ли это ошибкой ОС?
Спасибо,
Ваш код 'recv()' не обрабатывает неожиданный конец потока правильно. Цикл должен заканчиваться, если 'recv()' возвращает ноль или -1. И если вы получите сообщение об ошибке из 'send()' или 'recv()', то не достаточно просто распечатать собственное сообщение. Вы должны получить фактическую ошибку там где-нибудь, с 'perror()' или 'strerror()'. – EJP
Да. Я должен. Из кода, который у меня выше, если 'recv()'/'send()' return -1, то функция завершится. Если они возвращают 0, тогда он должен печатать число байтов recv/send равно 0. Но такое сообщение не было распечатано, когда сбой переданного двоичного файла. – Ling
Вы уверены, что buf размер большой? (Так как пример не завершен, и в его текущей форме он выглядит okey). Если вы hexdump поврежденный файл, какой вид вы видите? У вас есть доступность? Это всегда удобно, что может обнаружить некоторые проблемы с памятью. –