服务器不等待客户端在C中的套接字上写入数据

时间:2014-11-15 16:29:26

标签: c sockets

我目前正在C中构建一个服务器/客户端应用程序。我正在完成任务,因此我无法共享任何代码,但我希望你能帮我解决一些问题。无论如何,关于我的问题。

假设服务器正在运行并接受来自多个客户端的连接。一旦客户端成功建立连接,它就会询问用户要执行的操作 - 让他们调用ACTION 1ACTION 2并假设用户选择第一个并点击 Enter - 所以客户端在套接字上写了代表用户选择的代码,服务器从套接字中读取它并发回代码让客户知道它没问题。

下一步是从用户收集数据并将其发送到服务器。理想情况下,这将按此顺序发生:

  1. 客户端要求用户输入;
  2. 客户端在套接字上写入数据;
  3. 服务器从套接字读取数据;
  4. 服务器使用提供的数据执行操作;
  5. 服务器发送反馈。
  6. 当(1)仍在进行时,服务器从(我认为是)空套接字读取并且不等待客户端写入和发送数据。所以(3)发生,服务器明显崩溃。在执行任何需要的操作之前,如何使服务器等待数据?

    服务器端

    void *deal_with_user(void *arg)
    {
        int action = 0;
        int status = 0;
    
        ConnectingUser* user = (ConnectingUser *) arg;
    
        action = request_action(user);
    
        if (action == ACTION_1)
        {
            if ((status = perform_action(user)) != ACTION_GRANTED)
            {
                pthread_exit((void *) 0);
            }
        }
        else if (action == ACTION_2)
        {
            // do nothing yet
        }
        else
        {
            pthread_exit((void *) 0);
        }
    
    
        /*
        *
        *   More code...
        *
        */
    
        pthread_exit((void *) 0);
    }
    
    int request_action(ConnectingUser *user)
    {
        int status = 0;
    
        while (!status)
        {
            status = read_user_action(user);
    
            /*
            *
            * Error Handling code
            *
            */
    
        return status;
    }
    
    int read_user_action(ConnectingUser *user)
    {
        int read_bytes;
        int status;
        char *action_code;
    
        read_bytes = 0;
        action_code = (char *) calloc (4, sizeof(char));
    
        if ((read_bytes = read(user->user_socket_descriptor, action_code, 4)) <= 0)
        {
            if (read_bytes < 0)
            {
                fprintf(stderr, "Error read_user_action()\n");
                status = READ_ACTION_ERR;
            }
            else if (read_bytes == 0)
            {
                status = BROKEN_PIPE;
            }
        }
        else
        {
            if (write(user->user_socket_descriptor, "OKCODE", 6) < 0)
            {
                fprintf(stderr, "Error read_user_action()\n");
                free(action_code);
                return WRITE_ACTION_ERR;
            }
    
            // get_action() returns either ACTION_1 or ACTION_2
            status = get_action(action_code);
        }
    
        free(action_code);
        return status;
    }
    
    int perform_action(ConnectingUser *user)
    {
        int status = 0;
    
        while (!status)
        {
            status = authorize_action(user);
    
            /*
            *
            * Error Handling code
            *
            */
    
        return status;
    }
    
    int authorize_action(ConnectingUser *user) 
    {
        int read_bytes;
        int status;
        char *action_data;
        NeededData *client_data = NULL;
    
    
        read_bytes = 0;
        action_data = (char *) malloc (MAX_LENGTH*sizeof(char));
    
        if ((read_bytes = read(user->user_socket_descriptor, action_data, MAX_LENGTH)) <= 0)
        {
            if (read_bytes < 0)
            {
                fprintf(stderr, "Error authorize_action()\n");
                free(action_data);
                return READ_DATA_ERR;
            }
            else if (read_bytes == 0)
            {
                free(action_data);
                return BROKEN_PIPE;
            }
        }
        else
        {
            printf("I have read something: %s\n", action_data);
        }
    
    
        if (checks_out(user, user_list, client_data))
        {
            if (write(user->user_socket_descriptor, "OK-ACT", 6) < 0)
            {
                fprintf(stderr, "Errore authorize_login(): impossibile inviare auth\n");
                free(action_data);
                free(client_data);
                return WRITE_INFO_ERR;
            }
            status = ACTION_GRANTED;
        }
        else
        {
            if (write(user->user_socket_descriptor, "NO-ACT", 6) < 0)
            {
                fprintf(stderr, "Errore authorize_login(): impossibile inviare auth\n");
                free(action_data);
                free(client_data);
                return WRITE_INFO_ERR;
            }
            status = INCORRECT_ACTION;
        }
    
        free(action_data);
        free(client_data);
    
        return status;
    }
    

    客户端

    int ask_for_action()
    {
        int action = 0;
        int status = 0;
        char *input;
    
        input = (char *) calloc(2, sizeof(char));
    
    
        while (!status)
        {
            fprintf(stdout, "Pick action\n");
            fprintf(stdout, "[1] Action One\n[2] Action Two\n\nInput: ");
            fgets(input, 2, stdin);
            getchar();
    
               /*
                *
                * Error Handling code
                *
                */
    
                action = write_action(action);
                status = action_one();
    
               /*
                *
                * Error Handling code
                *
                */
            }
        }
    
        free(input);
        return action;
    }
    int write_action(const int action)
    {
        int read_chars;
        char *action_code;
        char *server_ans;
    
           /*
            *
            *  More code
            *
            */
    
        // Stores the action code
        action_code = (char *) calloc (4, sizeof(char));
        // Stores server response
        server_ans = (char *) calloc (6, sizeof(char));
    
        if (write(socket_descriptor, action_code, sizeof(action_code)) < 0)
        {
            fprintf(stderr, "Errore write_action()\n");
            free(action_code);
            return WRITE_ACTION_ERR;
        }
    
        free(action_code);
    
        if ((read_chars = read(socket_descriptor, server_ans, 6)) <= 0)
        {
           /*
            *
            *  Error Handling
            *
            */
        }
    
        if (strncmp(server_ans, "OK-ACT", 6) == 0)
        {
            if (cc.debug)
            {
                fprintf(stdout, "Action sent correctly.\n");
            }
    
            free(server_ans);
            return action;
        }
    
        // Code...
    }
    
    int action_one()
    {
       // Server should wait for this function to gather input from user, but by
       // the time this is called, the server has moved on and crashed.
    }
    

    编辑1

    我发现在客户端发送动作代码之后,服务器读取3个字节---未在屏幕上打印出来,它们是\0\n,我猜---在崩溃之前。我试过刷新输入,但它没有摆脱这些字节并继续读取它们。

0 个答案:

没有答案