c - 简单客户端/服务器的问题,文件打印错误

标签 c sockets pthreads

基本上,服务器需要将客户端填充的结构打印到文件中,客户端和服务器都应该在 message.fine == 1 时停止。问题是每次创建文件时,它都会填充数千个为零,这表明读写功能没有正常工作。你能帮我解决这个问题吗?

这是客户端:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

struct Data 
{
    int a;
    float b;
    int fine;
    int risultato;
};

int main()
{   
    int sock;
    struct Data message, response;
    message.fine = 0;

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(6869);
    address.sin_addr.s_addr = inet_addr("127.0.0.1");

    sock = socket(AF_INET, SOCK_STREAM, 0);

    connect(sock, (struct sockaddr *)&address, sizeof(address));

    while(message.fine != 1)
    {   
        printf("\nInsert an integer number:");
        scanf("%d", &message.a);
        printf("\nInsert a float number:");
        scanf("%f", &message.b);
        printf("\nIs this the final message? (0 = no, 1 = yes)\n");
        scanf("%d", &message.fine);


        write(sock, &message, sizeof(struct Data));
        read(sock, &response, sizeof(struct Data));

        if(response.risultato == -1)
        {
            fprintf(stderr, "\nServer returned Writing Error\n");
            exit(EXIT_FAILURE);
        }
        else if(response.risultato == 1)
        {
            printf("\nSuccess in Operation\n");
        }
    }
    close(sock);
    exit(EXIT_SUCCESS);
}

这是服务器:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

struct Data 
{
    int a;
    float b;
    int fine;
    int risultato;
};



void * handler(void * args)
{
    struct Data message;    
    int sock = *(int *)args;
    FILE *fp;

     if(!(fp = fopen("result.txt", "a")))
        {
        fprintf(stderr, "Error in opening file\n");
        exit(EXIT_FAILURE);
        }

    while(1)
    {

        read(sock, &message, sizeof(struct Data));

        printf("%d, %f, %d", message.a, message.b, message.fine);

        if(fprintf(fp,"\n[%d] [%.2f]\n", message.a, message.b) < 0)
        {
            message.risultato = -1;
        }
        else{
            message.risultato = 1;
        }

        if(message.fine == 1)
        {
            break;
        }
        write(sock, &message, sizeof(struct Data));

    }
    fclose(fp);
    close(sock);
    free(args);
    pthread_exit(NULL);
}


int main()
{
    int sock, client_sock;
    int * new_sock;

    pthread_t tid;

    struct sockaddr_in address, client_address;
    address.sin_family = AF_INET;
    address.sin_port = htons(6869);
    address.sin_addr.s_addr = inet_addr("127.0.0.1");

    socklen_t sock_len = (socklen_t)sizeof(address);


    sock = socket(AF_INET, SOCK_STREAM, 0);

    bind(sock, (struct sockaddr *)&address, sock_len);

    listen(sock, 3);

    while(1)
    {
       new_sock = (int *)malloc(sizeof(int));
       sock_len = sizeof(client_address);
       client_sock = accept(sock, (struct sockaddr *)&client_address, &sock_len); 
       *new_sock = client_sock;       
       pthread_create(&tid, NULL, handler, (void *)new_sock);
       pthread_detach(tid);
    }

}

实际结果应该是message.a和message.b中的数字依次打印在文件上。

最佳答案

The problem is that every time the file is created, it gets filled with thousands of zero, which indicates that the read and write function didn't work correctly

警告您使用 SOCK_STREAM,您无法保证在一次读取时读取所有预期的字节。

在服务器中你需要检查结果

   read(sock, &message, sizeof(struct Data));

在所有 if 未被读取时中断或再次读取,否则当未读取任何内容或读取小于预期大小时 message 完全或部分未更改或未设置,如果它位于第一个循环,你有一个机会循环到时间结束,当然你在文件中打印的值也没有改变或无效。

您遇到的可能情况是:在服务器的交换期间(可能是第一次)read 没有读取所有结构,因为 message.fine 未设置为 1 并且其他一些值也未设置,因为 message.fine != 1 您再次循环并再次读取,但是从未读字节而不是从结构的开头读取,因此,即使您读取了 sizeof(Data) 字节,但该结构没有很好地填充,而且 message.fine 也没有设置为 1 并且其他属性未设置为正确的值等,此时没有什么可读的,你会无限期地循环,因为消息保持不变。

当然我鼓励你也检查一下write的结果,当你读入你的客户端时你也有同样的问题

关于c - 简单客户端/服务器的问题,文件打印错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54483782/

相关文章:

linux - 为什么线程消息以相反的顺序出现?

c++ - 在不锁定互斥锁的情况下调用 pthread_cond_signal

使用指向第一个节点(头节点)的指针打印单个链表时的 C 段错误

c - 两行不同的代码第一次不起作用,然后又起作用

互联网上的 Java 套接字

linux - 一个打开的套接字可以长时间不读取吗?

c++ - pthread_cond_timedwait() & pthread_cond_broadcast() 解释

c - 如何使用CMake计算C项目的构建时间

c - fputs() 到 fgets() 之后的同一控制台行

sockets - 为什么不能将mmap与套接字fd一起使用?