使用 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_BUFFsizeof(buffer) 即可。

  • 客户端的fwrite()中的
  • sizeof(*argv)是错误的。 *argv(又名 argv[0])是 char*,而不是 char。您需要使用 sizeof(char)1

  • 客户端既没有向服务器发送命令的空终止符也没有发送命令的长度,那么您如何期望服务器知道何时到达命令结尾?在 TCP 中写入和读取之间没有 1:1 关系,因此您必须以一种或另一种方式考虑数据的实际大小。

  • 客户端调用fread()时,&bufferstrlen(buffer)sizeof(BUFF_SIZE)都是错误的。虽然 &buffer 可能有效,但 strlen(buffer) 肯定不会,因为 buffer 尚未填充以 null 结尾的字符串,因此您需要使用 sizeof(char)1 代替。 sizeof(BUFF_SIZE) 需要只是 BUFF_SIZEsizeof(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);
    }
}