我试图通过TCP连接传递结构变量,但我无法理解哪个是问题。我得到变量命令和id,但是当我读取用户名变量(以及之后的那些)时,printf没有给出结果。
typedef struct _msg{ // 4+4+20+20+44+200+8=300
int command;
int id;
char username[20];
char password[20];
char subject[44];
char text[200];
time_t timestamp;
} msg;
msg* get_msg(int client_socket){
char *auxString= (char*) calloc (1, sizeof(time_t));
msg *auxMsg= (msg*) calloc(1,sizeof(msg));
read(client_socket, auxString , sizeof(auxMsg->command));
auxMsg->command=strtol(auxString,NULL,10);
printf("%d\n", auxMsg->command);
read(client_socket, auxString, sizeof(auxMsg->id));
auxMsg->id=strtol(auxString,NULL,10);
printf("%d\n", auxMsg->id);
read(client_socket, auxMsg->username, sizeof(auxMsg->username));
printf("%s\n", auxMsg->username);
read(client_socket, auxMsg->password, sizeof(auxMsg->password));
printf("%s\n", auxMsg->password);
read(client_socket, auxMsg->subject, sizeof(auxMsg->subject));
printf("%s\n", auxMsg->subject);
read(client_socket, auxMsg->text, sizeof(auxMsg->text));
printf("%s\n", auxMsg->text);
read(client_socket, auxString , sizeof(auxMsg->timestamp));
auxMsg->timestamp=strtol(auxString,NULL,10);
printMsg(auxMsg);
return auxMsg;
}
int send_msg(int client_socket, int command, int id, char* username, char* password, char*subject, char*text, time_t timestamp){
char* auxString=(char*) calloc (1,sizeof(time_t));
sprintf(auxString,"%d",command);
write(client_socket,auxString,sizeof(int));
sprintf(auxString,"%d",id);
write(client_socket,auxString,sizeof(int));
write(client_socket,username,sizeof(username));
write(client_socket,password,sizeof(password));
write(client_socket,subject,sizeof(subject));
write(client_socket,text,sizeof(text));
sprintf(auxString,"%d",command);
write(client_socket, auxString, sizeof(time_t));
return SUCCESS;
}
答案 0 :(得分:1)
您的struct
似乎包含固定长度的字符串字段,但在send_msg
函数中,您只是传递指针。
因此,当您使用sizeof
时,您只需传递指针的大小(通常在32位系统上为4,在64位系统上为8) 字符串的长度。
我强烈建议您更改send_msg
函数,以便它还需要msg*
指针而不是单个字段,然后使用单独的函数从这些字段构建此类结构。
完成此操作后,您的send_msg
函数将简化为:
ssize_t send_msg(int client_socket, msg *m) {
return write(client_socket, m, sizeof(msg));
}
同样get_msg()
会缩减为:
msg *get_msg(int client_socket) {
msg *m = malloc(sizeof(msg));
if (m) {
char *p = (char *)m;
ssize_t r = 0;
size_t n = sizeof(msg);
while ((r = read(client_socket, p, n)) > 0) {
n -= r;
p += r;
}
if (r == -1) { /* an error occurred */
free(m);
m = NULL;
}
}
return m;
}
即。 (最多)每次调用read
或write
,其中int
字段以二进制形式传输。 get_msg
函数显示了在获得整个结构之前如何继续阅读 - send_msg
函数理想情况下看起来也一样。
但是你应该注意这里有一些注意事项:
首先,传输的数据将始终是struct msg
的完整大小,即使其中的字符串未填充其缓冲区。更优化的协议将传输字符串长度,然后传输字符串数据。
其次,二进制数据的格式将取决于体系结构,因此如果一端是little-endian而另一端是big-endian,则代码将无法工作。然而,后者可以通过使用htonl()
和相关函数来简单地修复,以便在传输之前将二进制字段转换为规范的“网络顺序”,并在收到时转换回ntohl()
。