我正在处理将数据发送到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; }
}
}
答案 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);
}