Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Read在几次操作后返回0_C++_Linux_Pipe_Posix - Fatal编程技术网

C++ Read在几次操作后返回0

C++ Read在几次操作后返回0,c++,linux,pipe,posix,C++,Linux,Pipe,Posix,我在客户端和服务器之间有一个TCP多线程通信。我不知道为什么第三次使用read函数时它只给出0 客户端代码 我获得了登录和用户的正确读数,但在读取parola时,它只返回0,然后我才能在客户端窗口中输入内容。显示的代码中存在多个错误读取()返回0是观察到的最小问题。事实上,这可能只是所示代码中所有其他问题的最终结果,而不是真正的原因。第一个主要问题多次出现,最好的例子是服务器代码: write (fd, mesaj_catre_client, sizeof(mesaj_catre_client)

我在客户端和服务器之间有一个TCP多线程通信。我不知道为什么第三次使用read函数时它只给出0

  • 客户端代码

  • 我获得了登录和用户的正确读数,但在读取parola时,它只返回0,然后我才能在客户端窗口中输入内容。

    显示的代码中存在多个错误<代码>读取()返回0是观察到的最小问题。事实上,这可能只是所示代码中所有其他问题的最终结果,而不是真正的原因。第一个主要问题多次出现,最好的例子是服务器代码:

    write (fd, mesaj_catre_client, sizeof(mesaj_catre_client));
    
    此代码正在写入套接字。这将完全忽略
    write()
    中的返回代码。写入套接字时,您绝对不能保证所有内容都会写入套接字。您需要在此处写入
    sizeof(mesaj_catre_客户端)
    字节数。很遗憾,你不能保证所有这些字节都会被写入
    write()
    只能写入mesaj_catre_客户端的第一个字节,并返回1。或者写入此结构的一半,并返回实际写入的字节数。您的代码必须对此进行检查,但您的代码忽略了它,因此您不知道在这里到底写入了哪些套接字

    必须检查每次调用
    write()
    的返回值,并相应调整程序的逻辑。通常的解决方案是重复
    write()
    ,这一次是对剩余的字节

    从套接字读取时会出现相同的逻辑错误:

    if (read(sd, msg, 1024) < 0) {
    

    所示代码为C++代码,使用C++类。现代C++是类型安全的。任何现代C++代码都不需要使用<代码> Malc C <代码>或<代码>免费< /代码>,或从<代码> Value*/COD>中转换。这在这里是必要的,因为您使用的是C API。应将其替换为类型安全的

    std::thread
    ,并且无需
    malloc
    new
    任何内容


    但是所示代码的根本问题是它没有准备好,并且不能正确处理套接字的读/写语义,这对每个
    read()
    write()
    调用中读取和写入的内容几乎没有保证。您不能做出任何类型的假设,必须小心地实现正确的逻辑,以便从套接字写入和读取单个字节,并将它们组装到读取和写入的逻辑结构中。无论是
    read()
    还是
    write()
    都不能为您做到这一点,必须自己实现所有逻辑。

    如果您能将您的评论[和消息]从罗马尼亚语翻译成英语,可能会有所帮助。我之所以知道他们是罗马尼亚人,是因为我将:
    parametru functia executata de thread
    放入谷歌翻译,然后返回:
    线程执行的参数函数。此外,这似乎是
    c++
    而不是
    c
    ,因此您可能希望删除
    c
    标记。但是,乍一看,您没有检查一些函数的返回值(例如
    读取
    写入
    )。而且,(例如)你正在做:
    sprintf(mesaj_catre_客户,“引见我的帕罗拉:”);写入(fd、mesaj_catre_客户端、sizeof(mesaj_catre_客户端))但是,您最好使用:
    size\u t len=sprintf(mesaj\u catre\u客户机,“Improducti parola:”);写入(fd,mesaj_catre_客户端,len+1)。至少有两个主要问题:1。您总是写入整个缓冲区,因此如果用户输入“hi”,则发送“hi\0\0\0\0\0\0\0\0\0\0\0[…]”。2.您假设客户端的一次写入变成了服务器上的一次读取。一般来说,这是不正确的,当您写入大缓冲区并读取较小缓冲区时,这肯定是不正确的。由于您似乎需要基于行的协议,因此应该了解如何读取和写入行。由于您正在执行
    read(…,whatever,sizeof(whatever))
    ,您可能需要查看返回值,因为第一个
    read
    可以读取第一条消息,但缓冲区具有第二条消息的初始部分。(例如)如果发送方发送了两条消息(例如
    hello
    world
    ),接收方可能会收到
    helloworld
    作为第一条[也是唯一的]消息,因为它得到的是10个字节,而不是5个字节。请在代码注释中使用英语。您可能需要阅读更多有关的信息,包括。考虑使用或或部分。
    void ConectareServer::Conectare(int arg) {
        fd=arg;
        cout<<fd;
        memset(mesaj_catre_client, 0, 1024);
        sprintf(mesaj_catre_client,
                "Conectare reusita, pentru a continua, trebuie sa te loghezi. Sintaxa comenzilor este urmatoarea: \n<login>, pentru a realiza logarea la server\n"
                "<quit>, pentru a inchide programul");
        write(arg, mesaj_catre_client, sizeof(mesaj_catre_client));
        VerifComanda(arg);
    }
    void ConectareServer::VerifComanda(int fd) {
        memset(mesaj_catre_client, 0, 1024);
        memset(mesaj_de_la_client, 0, 1024);
        read(fd, mesaj_de_la_client, sizeof(mesaj_de_la_client));
        printf("[server]Mesajul a fost receptionat...%s\n", mesaj_de_la_client);
        if(strcmp(mesaj_de_la_client, "login")==0){
            Logare client(fd);
            client.Login();
            cout<<"Intra in Logare";
        }
        if (strcmp(mesaj_de_la_client, "quit") == 0) {
            sprintf(mesaj_catre_client, "Conexiune incheiata");
            write(fd, mesaj_catre_client, sizeof(mesaj_catre_client));
        }
        if(strcmp(mesaj_de_la_client, "login") != 0 && strcmp(mesaj_de_la_client, "quit") != 0)
        {
            cout<<"Crash";
        }
    }
    
    void Logare::Login() {
        memset(mesaj_catre_client, 0, 256);
        char user[10];
        char parola[8];
        sprintf(mesaj_catre_client,"Introduceti user-ul: ");
        write (fd, mesaj_catre_client, sizeof(mesaj_catre_client));
        read (fd, user, sizeof (user));
    
        printf ("[server]Mesajul a fost receptionat...%s\n", user);
    
        memset(mesaj_catre_client, 0, 256);
        sprintf(mesaj_catre_client,"Introduceti parola: ");
        write (fd, mesaj_catre_client, sizeof(mesaj_catre_client));
    
        read (fd, parola, sizeof (parola));
        printf ("[s]Mesajul a fost receptionat...%s\n", parola);
    
        if(Verificare_Logare(user,parola) == 1)
        {
            // Logare reusita
            Meniu client(fd, user);
            client.MeniuAplicatie();
    
        }
    }
    
    write (fd, mesaj_catre_client, sizeof(mesaj_catre_client));
    
    if (read(sd, msg, 1024) < 0) {
    
    td=(struct thData*)malloc(sizeof(struct thData));
    
    // ...
    
    static void *treat(void * arg)
    {
        struct thData tdL;
        tdL= *((struct thData*)arg);