我正在尝试使用C中的套接字传输文件(在本例中为.jpg文件)。我有我的客户端和服务器代码,但我不知道为什么传输文件的字节数比原始文件多文件。这是代码:
SERVER
/***************************************************
*
* Starting to send data file
*
***************************************************/
// Read the size of the file
recv(client.fd_client, &file.size_file, sizeof(int), 0);
recv(client.fd_client, &file.size_string, sizeof(int), 0);
recv(client.fd_client, &file.name_of_file, file.size_string, 0);
printf("Size of the file: %.3f kB\n", file.size_file/1000.);
printf("Receiving the file \"%s\"...\n", file.name_of_file);
if((file.fd_file = creat(file.name_of_file, S_IRWXU)) < 0) {
error("Can't open the file: ");
}
while(1) {
bzero(buffer, SIZE_BUF);
if((numb_bytes = read(client.fd_client, buffer, SIZE_BUF)) < 0) {
error("Can't read the file.");
}
write(file.fd_file, buffer, numb_bytes);
received += numb_bytes;
printf("Received: %.3fkB (%.3f/%.3f) kB\n", numb_bytes/1000., recibed/1000., file.size_file/1000.);
if(numb_bytes == 0)
break;
}
printf("Recibidos %.3f/%.3f kB\n", recibed/1000., file.size_file/1000.);
客户端
/***************************************************
*
* Starting to send data file
*
***************************************************/
// Use strncpy!
strcpy(file.name_of_file, argv[3]);
file.fd_file = open(file.name_of_file, 0);
fstat(file.fd_file, &stat_file);
file.size_file = (unsigned int) stat_file.st_size;
file.size_string = (unsigned int) strlen(file.name_of_file) + 1;
printf("Size of the file: %.3f kB.\n", file.size_file/1000.);
printf("Sending the file \"%s\"...\n", file.name_of_file);
// Send data file
write(conection.sockfd, &file.size_file, sizeof(file.size_file));
write(conection.sockfd, &file.size_string, sizeof(file.size_string));
write(conection.sockfd, &file.name_of_file, sizeof(file.name_of_file));
while(1) {
sended += sendfile(conection.sockfd, file.fd_file, NULL, SIZE_BUF);
printf("send: %d\n", sended);
printf("num_bytes: %d\n", num_bytes);
if(sended == file.size_file)
break;
}
printf("Sended %.3f/%.3f kB\n", sended/1000., file.size_file/1000.);
我有几个问题:
答案 0 :(得分:1)
您正在发送整个名称缓冲区:
write(conection.sockfd, &file.name_of_file, sizeof(file.name_of_file));
但只读取前一个字段发送的长度:
recv(client.fd_client, &file.size_string, sizeof(int), 0);
recv(client.fd_client, &file.name_of_file, file.size_string, 0);
缓冲区大小和字符串长度之间的差异可能是您对附加文件长度的差异。你可以通过改变这个来解决这个问题:
write(conection.sockfd, &file.name_of_file, sizeof(file.name_of_file));
,在您的客户端代码中:
write(conection.sockfd, &file.name_of_file, file.size_string);
我会查看其他子问题,但这是您的文件大小错误的主要原因。我无法对使用htonl
和ntohl
的正确性做出明智的决定,因为您没有包含传输这些字段的代码。这可能是一个问题。您可以在所有时间保持结构中的原始大小,并将它们读入临时变量,然后通过在接收方通过ntohl
发送所述变量来分配结果,并且只需在发送方发送临时变量(通过htonl
收到翻译后)。