0

This is the snippet of client code:

connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

strcpy(Buffer, filename);

send(DescrittoreClient, Buffer, strlen(Buffer), 0);
fd = open(filename, O_CREAT | O_WRONLY,0644);

while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) != 0) {
    write(fd, Buffer, nread);
    memset(Buffer,0,sizeof(Buffer));
}
int gg;
while( (gg = recv(DescrittoreClient, Buffer, sizeof(Buffer), 0)) == -1) continue;
printf("%d\n", gg);
printf("Risposta del server: %s\n", Buffer);

close(DescrittoreClient);
return EXIT_SUCCESS;

And this is the snippet of the server code:

while(1){

    rc = recv(DescrittoreClient, filename, sizeof(filename), 0);

    fd = open(filename, O_RDONLY);

    fstat(fd, &stat_buf);

    offset = 0;
    rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size);
    if (rc != stat_buf.st_size) {
        fprintf(stderr, "incomplete transfer from sendfile: %d of %d bytes\n", rc, (int)stat_buf.st_size);
        exit(1);
    }
    strcpy(Buffer, "Dati inviati correttamente");
    if( (send(DescrittoreClient, Buffer, strlen(Buffer), 0)) == -1){
        printf("Errore nell'invio della stringa\n");
        close(DescrittoreClient);
        close(fd);
        exit(1);
    }

}
close(DescrittoreServer);
return EXIT_SUCCESS;

This is the expected behaviour:

Client --Give me file X--> Server
Server --send the file X--> Client
Server -->send string "File has been sent"--> Client

But this is the real behaviour:

Client --Give me file X--> Server
Server --send the file X--> Client
Server -->_NOTHING_--> Client

So the problem is that the client doesn't receive "File has been sent". I've checked if the problem is server's side but it isn't (in fact the server send the string)

9
  • 3
    Too much code! Reduce it to a minimum while still reproducing the problem. Commented Jun 17, 2012 at 15:08
  • What is (Buffer) declared as? Commented Jun 17, 2012 at 16:49
  • if read() returns a negative value, the subsequent write() call is going to try to write (size_t)-1 bytes into your file, which will probably crash your client program. Commented Jun 17, 2012 at 16:51
  • Calling memset(Buffer, 0, sizeof(Buffer)) isn't necessary (or helpful) since you never use any bytes from Buffer that you read() didn't just write to anyway. Commented Jun 17, 2012 at 16:53
  • 1
    How does your receiving code know when the bytes of the file have ended and the bytes of the string begin? Most likely you'll find that the bytes of your string got lumped in with the file data and are present now at the end of the received file... :^/ Commented Jun 17, 2012 at 20:42

1 Answer 1

2

(based on the comments above) -- the thing to realize is that TCP communication is 100% stream based, with no built-in framing. That means that all the TCP layer does is make sure that the receiver receives the bytes in the same order that the sender sent them -- but it does not guarantee that the bytes will be received in the same intervals as they were sent. (For example, if you send() 10 bytes, then 20 bytes, then 50 bytes, the receiver might receive all 80 bytes at once, or 63 bytes followed 17 bytes, or any other combination of recv()s that sum up to 80 bytes total).

Therefore in order to send multiple separate items in such a way that the receiver can interpret them correctly, you need to define your own rules for framing the data. In your case you need to send n bytes of file data, followed by a string, and what your receiving program needs to know is how many bytes of file data to expect. That way, once it has received (that many) bytes, it knows the remaining bytes are string data and won't just write them to the file.

My suggestion would be to send the file's size first (either as a 4-byte integer, or an 8-byte long if you need to support file sizes greater than 4 gigabytes). Then the receiving code would be like this:

  1. Receive 4 bytes
  2. Interpret those four bytes as an integer (you may want to pass this value through htonl() on the sender and ntohl() on the receiver, in order to avoid possible endian-ness issues here)
  3. Receive N bytes and write them to the file
  4. Receive any remaining bytes as a string.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.