简体   繁体   中英

How to send a size_t variable with a TCP socket in C?

I'm working on something that sends data to a TCP server, but first it is supposed to send the size of the data in 8 bytes.

That is, the server will read the first 8 bytes sent to it and cast them back into a size_t variable. My problem is, when there is a file size that doesn't use any of the top bits (ie 83 = 0000000S <- char's, not hex), it only sends the non-zero bytes.

This is how I do it:

void send_file_to_server(char *filename){

    struct stat buf;
    if (stat(filename, &buf)==-1){ exit(1); }
    size_t file_size = buf.st_size;

    char *filesize_string = calloc(1, 8);
    filesize_string = (char*)&file_size;

    //this function actually writes to the server
    write_to_server((char*) filesize_string);


   // will be code later on that sends the actual file using write_to_server()

}

The char* passed into my write_to_server() function has some weird behavior: it only recognizes it as a string of size 6, and it gets distorted from before it was passed in. Any advice on how to make this work is appreciated.

Note: I do not have to worry about endianness (htonl, etc.) or a differing size of size_t since this is for a project that will only ever be run on a specific VM.

Edits:

here is the other function:

void write_to_server(char *message){
    ssize_t bytes_sent = 0;
    ssize_t message_size = strlen(message);

    while ( bytes_sent < message_size ){
        ssize_t ret = write(server_socket, message+bytes_sent, message_size-bytes_sent);
        if (ret==0){
            print_connection_closed(); 
            exit(1);
        }
        if (ret==-1 && (errno!=EINTR || errno!=EAGAIN)){
            printf("write failed: sent %zd bytes out of %zd\n", bytes_sent, message_size);
            exit(1);
        }
        if (ret!=-1){ bytes_sent+=ret; }
    }   
}

You can't use strlen() to determine the length of binary data. It'll miscount the data as soon as it sees a zero (NUL) byte in the binary encoding of the length field.

Write a more "primitive" function that takes the address of the data and its length as parameters, eg

void write_to_server_raw(const void *message, size_t message_size) {
    ...
}

If you still need the ability to send NUL terminated strings you can then rewrite your existing write_to_server() function so that it calls the new function to do the real work.

void write_to_server_string(const char *message) {
    size_t message_size = strlen(message);
    write_to_server_raw(message, message_size);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM