如何在C中使用TCP套接字发送size_t变量?

时间:2017-11-23 16:48:12

标签: c sockets tcp network-programming

我正在处理将数据发送到TCP服务器的事情,但首先它应该以8个字节发送数据的大小。

也就是说,服务器将读取发送给它的前8个字节并将它们转换回size_t变量。我的问题是,当文件大小没有使用任何顶部位(即83 = 0000000S< - char,而不是十六进制)时,它只发送非零字节。

我就是这样做的:

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()

}

传递给我的write_to_server()函数的char *有一些奇怪的行为:它只将它识别为大小为6的字符串,并且在传入之前它会被扭曲。有关如何使这项工作的任何建议都值得赞赏

注意:我不必担心字节顺序(htonl等)或size_t的大小不同,因为这是一个只能在特定VM上运行的项目。

编辑:

这是另一个功能:

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; }
    }   
}

1 个答案:

答案 0 :(得分:1)

您不能使用strlen()来确定二进制数据的长度。一旦在长度字段的二进制编码中看到零(NUL)字节,它就会错误计算数据。

写一个更“原始”的函数,它将数据的地址作为参数,例如

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

如果您仍然需要能够发送NUL终止字符串,则可以重写现有的write_to_server()函数,以便它调用新函数来完成实际工作。

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