我正在尝试使用TCP从Windows客户端向C语言中的Linux服务器发送文件。
我用来发送数据的缓冲区的大小是65535.当文件大小超过这个值时,我收到一个错误,说“通过peer重置连接”或错误代码10054.当文件大小时小于65535字节,服务器只接收其中的一部分(通常为2760字节)。
我只想发送最大大小为50 MB的文件。
这是我用来发送数据的Windows客户端的一部分:
char *fileName; // pointer to filename
char buf[65535]; // buffer
int fileSize; // # bytes to send
for(i = 0; i < ARRAYSIZE; i++) {
if(selectList[i] != NULL) {
// select file
fileName= selectList[i]; // get path and filename from selectList
printf("=============================================\nSending: %s\n", fileName);
filefd = fopen(fileName, "rb"); // open file
if(filefd == NULL) {
printf("File %s not found\n", fileName);
exit(1);
}
// read and send file
memset(buf, '\0', 65535);
while((fileSize= fread(buf, sizeof(char), 65535, filefd)) > 0) { // read file
if((numberOfBytes = send(sockfd, buf, fileSize, 0)) < 0) { // send buffer
printf("send: %s (Error: %d)\n", filename, WSAGetLastError());
break;
}
printf("#bytes = %i \n", numberOfBytes);
memset(buf, '\0', 65535);
}
printf("File %s send!\n", filename);
// close file after sending it
if(fclose(filefd) < 0) {
printf("fclose: %i", WSAGetLastError());
}
} else if(selectList[0] == NULL) {
printf("no files selected");
}
}
selectList包含多个字符串,例如:C:\ Windows \ test.txt
Linux服务器的接收部分:
char* fr_name = "/home/MtFS/UploadedFiles/public/testFile.gif";
FILE *fr = fopen(fr_name, "wb");
if(fr == NULL)
printf("[Open_File]file %s cannot be created\n", fr_name);
else {
bzero(revbuf, LENGTH);
int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0) {
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz) {
error("[Write] error\n");
}
bzero(revbuf, LENGTH);
if (fr_block_sz == 0 || fr_block_sz != 512) {
break;
}
}
if(fr_block_sz < 0) {
if (errno == EAGAIN) {
printf("[Receive] time out\n");
}
else {
printf("[Receive] error\n");
exit(1);
}
}
printf("[Receive] succesfull\n");
fclose(fr);
}
我做错了什么?
答案 0 :(得分:0)
你的问题是那3行代码。这不是了解你已经完成的正确方法:
if (fr_block_sz == 0 || fr_block_sz != 512) {
break;
}
另外,您要检查512而不是LENGTH。但只有0才意味着你已经完成了(假设你的连接不是NONBLOCKED。)
作为旁注:您不必在使用它们之前清除缓冲区(bzero,memset),因为read / recv会覆盖缓冲区的内容。
答案 1 :(得分:0)
我认为罪魁祸首就是服务器中的这一行
if (fr_block_sz == 0 || fr_block_sz != 512) {
fr_block_sz
可以是1
到65535
之间的任何内容 - 您发送的大小块。
在您的代码中,当它不是512
时,您的服务器就会终止连接。