使用 fwrite() TCP 服务器客户端发送结构的问题
problem of sending structure with fwrite() TCP Server client
我有一个帐户结构(如银行帐户),我想在应用程序启动时写“state”时将帐户信息发送给客户端:./client state
然后服务器必须发送客户端的信息,但是我在发送带有 fwrite 函数的结构时遇到问题,
我已经在我的 server.c
上实现了这个
...
if(strcmp(buffer, "state") == 0) {
printf("sending the state of account...\n");
memcpy(buffer, &a1, sizeof(a1));
printf("%s\n", buffer);
size_t nb_write = fwrite(buffer, sizeof(char), sizeof(MAX_BUFF), client_array[0].file);
printf("number i write: %ld\n", nb_write);
if(fflush(client_array[0].file)){
syserr("error of fflush");
}
}
在我的 client.c 上我写了这个:
...
if(argc > 1){
printf("argv[1]: %s\n", argv[1]);
size_t nb_write = fwrite(argv[1], sizeof(*argv), strlen(argv[1]), fdc);
printf("number i write: %ld\n", nb_write);
if(fflush(fdc)){
syserr("fflush");
}
}
size_t nbread = fread(&buffer, strlen(buffer), sizeof(BUFF_SIZE), fdc); // reception of structure
printf("number i read: %ld\n", nbread);
printf("%s\n", buffer);
应用程序客户端正在等待 fread()
./server
的输出:
number i read: 4
state
sending the state of account...
account 1
number i write: 4
error of fflush: Illegal seek
当我使用 CTRL-C 停止服务器时,应用程序客户端写入了一些奇怪的东西(可能是缓冲区的内容)并且应用程序也停止了。
Socket creation successful
Connection successful !
argv[1]: state
number i write: 5
number i read: 0
��E-�
这里是我要发送的结构:
struct account{
char title[MAX_TITLE_LENGTH];
struct user list_user[MAX_LIST_SIZE];
// char description[140]; // for example hotel, market, travel
int32_t total;
};
struct account a1;
/* ACCOUNT */
strcpy(a1.title, "account 1");
a1.list_user[0] = u1;
a1.total = 0.0;
我怎样才能修复它以在客户端的 fd 上正确发送结构并在我的客户端缓冲区上读取它
我看到这段代码中有很多错误:
服务器的fwrite()
中的sizeof(MAX_BUFF)
是错误的。您只需要使用 MAX_BUFF
或 sizeof(buffer)
即可。
客户端的fwrite()
中的sizeof(*argv)
是错误的。 *argv
(又名 argv[0]
)是 char*
,而不是 char
。您需要使用 sizeof(char)
即 1
。
客户端既没有向服务器发送命令的空终止符也没有发送命令的长度,那么您如何期望服务器知道何时到达命令结尾?在 TCP 中写入和读取之间没有 1:1 关系,因此您必须以一种或另一种方式考虑数据的实际大小。
客户端调用fread()
时,&buffer
、strlen(buffer)
、sizeof(BUFF_SIZE)
都是错误的。虽然 &buffer
可能有效,但 strlen(buffer)
肯定不会,因为 buffer
尚未填充以 null 结尾的字符串,因此您需要使用 sizeof(char)
即 1
代替。 sizeof(BUFF_SIZE)
需要只是 BUFF_SIZE
或 sizeof(buffer)
。
客户端和服务器中的 printf("%s\n", buffer);
都是错误的,因为 buffer
显然不是空终止字符串。
即使客户端不请求服务器发送它,客户端也希望接收该结构。
话虽如此,请尝试更像这样的事情:
...
char *cmd = NULL;
size_t size;
ssize_t len;
if ((len = getdelim(&cmd, &size, '[=10=]', client_array[0].file)) < 0) {
syserr("error of getdelim");
fclose(client_array[0].file);
}
else if (strcmp(cmd, "state") == 0) {
printf("sending the state of account...\n");
uint32_t size = htonl(sizeof(a1));
size_t nb_write = fwrite(&size, sizeof(size), 1, client_array[0].file);
if (nb_write == 1) {
nb_write = fwrite(&a1, sizeof(a1), 1, client_array[0].file);
}
if (nb_write < 1) {
syserr("error of fwrite");
fclose(client_array[0].file);
}
else {
printf("number i write: %ld\n", sizeof(size) + sizeof(a1));
if (fflush(client_array[0].file) != 0) {
syserr("error of fflush");
}
}
}
free(cmd);
...
if (argc > 1) {
printf("argv[1]: %s\n", argv[1]);
if (fwrite(argv[1], strlen(argv[1])+1, 1, fdc) < 1) {
syserr("error of fwrite");
fclose(fdc);
}
else if (fflush(fdc) != 0) {
syserr("fflush");
}
uint32_t size;
size_t nb_read = fread(&size, sizeof(size), 1, fdc);
if (nb_read == 1) {
size = ntohl(size);
nb_read = fread(buffer, size, 1, fdc);
}
if (nb_read < 1) {
syserr("error of fread");
fclose(fdc);
}
else {
printf("number i read: %ld\n", sizeof(size) + size);
printf("%.*s\n", size, buffer);
}
}
我有一个帐户结构(如银行帐户),我想在应用程序启动时写“state”时将帐户信息发送给客户端:./client state
然后服务器必须发送客户端的信息,但是我在发送带有 fwrite 函数的结构时遇到问题,
我已经在我的 server.c
...
if(strcmp(buffer, "state") == 0) {
printf("sending the state of account...\n");
memcpy(buffer, &a1, sizeof(a1));
printf("%s\n", buffer);
size_t nb_write = fwrite(buffer, sizeof(char), sizeof(MAX_BUFF), client_array[0].file);
printf("number i write: %ld\n", nb_write);
if(fflush(client_array[0].file)){
syserr("error of fflush");
}
}
在我的 client.c 上我写了这个:
...
if(argc > 1){
printf("argv[1]: %s\n", argv[1]);
size_t nb_write = fwrite(argv[1], sizeof(*argv), strlen(argv[1]), fdc);
printf("number i write: %ld\n", nb_write);
if(fflush(fdc)){
syserr("fflush");
}
}
size_t nbread = fread(&buffer, strlen(buffer), sizeof(BUFF_SIZE), fdc); // reception of structure
printf("number i read: %ld\n", nbread);
printf("%s\n", buffer);
应用程序客户端正在等待 fread()
./server
的输出:
number i read: 4
state
sending the state of account...
account 1
number i write: 4
error of fflush: Illegal seek
当我使用 CTRL-C 停止服务器时,应用程序客户端写入了一些奇怪的东西(可能是缓冲区的内容)并且应用程序也停止了。
Socket creation successful
Connection successful !
argv[1]: state
number i write: 5
number i read: 0
��E-�
这里是我要发送的结构:
struct account{
char title[MAX_TITLE_LENGTH];
struct user list_user[MAX_LIST_SIZE];
// char description[140]; // for example hotel, market, travel
int32_t total;
};
struct account a1;
/* ACCOUNT */
strcpy(a1.title, "account 1");
a1.list_user[0] = u1;
a1.total = 0.0;
我怎样才能修复它以在客户端的 fd 上正确发送结构并在我的客户端缓冲区上读取它
我看到这段代码中有很多错误:
-
服务器的
sizeof(MAX_BUFF)
是错误的。您只需要使用MAX_BUFF
或sizeof(buffer)
即可。
客户端的sizeof(*argv)
是错误的。*argv
(又名argv[0]
)是char*
,而不是char
。您需要使用sizeof(char)
即1
。客户端既没有向服务器发送命令的空终止符也没有发送命令的长度,那么您如何期望服务器知道何时到达命令结尾?在 TCP 中写入和读取之间没有 1:1 关系,因此您必须以一种或另一种方式考虑数据的实际大小。
客户端调用
fread()
时,&buffer
、strlen(buffer)
、sizeof(BUFF_SIZE)
都是错误的。虽然&buffer
可能有效,但strlen(buffer)
肯定不会,因为buffer
尚未填充以 null 结尾的字符串,因此您需要使用sizeof(char)
即1
代替。sizeof(BUFF_SIZE)
需要只是BUFF_SIZE
或sizeof(buffer)
。
客户端和服务器中的 printf("%s\n", buffer);
都是错误的,因为buffer
显然不是空终止字符串。即使客户端不请求服务器发送它,客户端也希望接收该结构。
fwrite()
中的fwrite()
中的话虽如此,请尝试更像这样的事情:
...
char *cmd = NULL;
size_t size;
ssize_t len;
if ((len = getdelim(&cmd, &size, '[=10=]', client_array[0].file)) < 0) {
syserr("error of getdelim");
fclose(client_array[0].file);
}
else if (strcmp(cmd, "state") == 0) {
printf("sending the state of account...\n");
uint32_t size = htonl(sizeof(a1));
size_t nb_write = fwrite(&size, sizeof(size), 1, client_array[0].file);
if (nb_write == 1) {
nb_write = fwrite(&a1, sizeof(a1), 1, client_array[0].file);
}
if (nb_write < 1) {
syserr("error of fwrite");
fclose(client_array[0].file);
}
else {
printf("number i write: %ld\n", sizeof(size) + sizeof(a1));
if (fflush(client_array[0].file) != 0) {
syserr("error of fflush");
}
}
}
free(cmd);
...
if (argc > 1) {
printf("argv[1]: %s\n", argv[1]);
if (fwrite(argv[1], strlen(argv[1])+1, 1, fdc) < 1) {
syserr("error of fwrite");
fclose(fdc);
}
else if (fflush(fdc) != 0) {
syserr("fflush");
}
uint32_t size;
size_t nb_read = fread(&size, sizeof(size), 1, fdc);
if (nb_read == 1) {
size = ntohl(size);
nb_read = fread(buffer, size, 1, fdc);
}
if (nb_read < 1) {
syserr("error of fread");
fclose(fdc);
}
else {
printf("number i read: %ld\n", sizeof(size) + size);
printf("%.*s\n", size, buffer);
}
}