Reputation: 908
I'm trying to transfer files (in this case, a .jpg file) with sockets in C. I have my client and my server code, but I don't know why the transfer file has more bytes than the original file. Here's the code:
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.);
CLIENT
/***************************************************
*
* 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.);
And I have a couple of questions:
Upvotes: 0
Views: 201
Reputation: 66194
You're sending the entire name buffer:
write(conection.sockfd, &file.name_of_file, sizeof(file.name_of_file));
but reading only the length sent from the previous field:
recv(client.fd_client, &file.size_string, sizeof(int), 0);
recv(client.fd_client, &file.name_of_file, file.size_string, 0);
The difference between the buffer size and the string length is likely you're differential of additional file length. You can address this by changing this:
write(conection.sockfd, &file.name_of_file, sizeof(file.name_of_file));
to this, in your client code:
write(conection.sockfd, &file.name_of_file, file.size_string);
I'll review the additional sub-questions, but this is the primary reason your file size is wrong. I can't really make an educated decision on the correctness of your use of htonl
and ntohl
because you didn't include the code that transmogs those fields. It could be a problem with that. you may way to keep the sizes native in the structures at all times, and read them into temp vars, assigning the results afterward by sending said-vars through ntohl
on the receiving side, and just sending the temp vars (after they receive the translations via htonl
) on the sending side.
Upvotes: 1