Код отправки имеет много логических ошибок:
отсутствие адекватной обработки ошибок.
передача неверного размера буфера в send()
(подсказка, для последнего буфера не будет 1024, если размер файла не кратен 1024).
при условии, что send()
отправляет весь буфер за один раз (намек, это редко бывает). Вам нужно вызывать send()
в цикле, пока не будет отправлен весь буфер.
неверно истолковывает возвращаемое значение send()
(подсказка, оно не возвращает логическое значение). Возвращает фактическое количество отправленных байтов (ну, число байтов, принятых во внутренний буфер сокета для передачи в фоновом режиме).
добавляя неправильное значение к total
после каждогоsend()
, поскольку предполагается, что send()
весь буфер за один раз.
отправка строки разделителя в конце файла, независимо от того, мог ли такой разделитель появитьсяв отправляемом файле. Вместо этого было бы безопаснее отправлять размер файла перед отправкой байтов файла.
указав неправильный размер буфера при отправке строки разделителя (подсказка, "Done"
не имеет размер 1024 байта).
утечка filewrite
ручки. Вы не звоните fclose()
для этого.
Сказав это, попробуйте что-то более похожее на это:
BOOL SendRaw(const void *buffer, int size) {
const char *ptr = (const char*)buffer;
int numSent;
while (size > 0) {
numSent = send(s, ptr, size, 0);
if (numSent == -1)
return FALSE;
ptr += numSent;
size -= numSent;
}
return TRUE;
}
BOOL SendFile(const wchar_t* file) {
FILE* filewrite = fopen("test.txt", "a");
if (!filewrite)
return FALSE;
FILE* fp = _wfopen(file, L"rb");
if (!fp) {
fclose(filewrite);
return FALSE;
}
if (fseek(fp, 0, SEEK_END) != 0) {
fclose(fp);
fclose(filewrite);
return FALSE;
}
long size = ftell(fp);
if (size == -1L) {
fclose(fp);
fclose(filewrite);
return FALSE;
}
rewind(fp);
uint32_t tmp = htonl(size);
if (!SendRaw(&tmp, sizeof(tmp))) {
fclose(fp);
fclose(filewrite);
return FALSE;
}
unsigned char buffer[1024];
int numBytes, numSent, total = 0;
while (size > 0) {
numBytes = fread(buffer, 1, min(sizeof(buffer), size), fp);
if (numBytes < 1) {
fclose(fp);
fclose(filewrite);
return FALSE;
}
if (!SendRaw(buffer, numBytes)) {
fclose(fp);
fclose(filewrite);
return FALSE;
}
size -= numBytes;
total += numBytes;
fprintf(filewrite, "%d\n", total);
}
fclose(fp);
fclose(filewrite);
return TRUE;
}
import struct
def recv_file_from_client(conn):
f = open("torecv","wb")
data = conn.recv(4)
if not data:
print "Error recv"
return
size = struct.unpack("!I", data)[0]
while(size > 0):
data = conn.recv(min(1024, size))
if not data:
print "Error recv"
return
f.write(data)
size -= len(data)
f.close()
print "Done recv"