尝试使用C套接字接受与Pthread的新连接

时间:2018-10-22 08:47:18

标签: c sockets tcp pthreads

我正在尝试制作一款《扫雷》,其中多个玩家可以访问服务器来玩游戏。我在努力使用Pthreads允许同时连接多个游戏。该程序以我的main方法启动,然后调用setup_listener,然后调用get_clients。我是pthread和套接字编程的新手,我的理解是,对于每个添加的新客户端,都应该创建一个新线程。 authenticate_process方法用于检查客户端的用户名和密码。目前,一旦我使用pthread_create,我的游戏逻辑就从功能menu_option开始,将当前客户端套接字传递给它。当我运行第一个新客户端时,我的程序可以正常运行,但是,当我启动第二个客户端时,我的程序则处于空闲状态。有人可以告诉我或向我解释解决我的问题需要做什么。

/* Global Variables */
int num_conn = 0;
int player_count = 0;
pthread_mutex_t mutexcount;
 /*
 * Main Program
 */
int main(int argc, char *argv[])
{
    int port;
    /* Make sure a port was specified. */
    if (argc < 2) {
        fprintf(stderr,"No port provided using port 12345\n");
        port = 12345;
    }
    else {
        port = atoi(argv[1]);
    }    

    int lis_sockfd = setup_listener(port); /* Listener socket. */
    pthread_mutex_init(&mutexcount, NULL);

    while (1) {
            int *cli_sockfd = (int*)malloc(2*sizeof(int)); /* Client sockets */
            memset(cli_sockfd, 0, 2*sizeof(int));

            /* Get clients connected. */
            get_clients(lis_sockfd, cli_sockfd);


                pthread_t thread; /* Don't really need the thread id for anything in this case, but here it is anyway. */
                int result = pthread_create(&thread, NULL, menu_option, (void *)cli_sockfd); /* Start a new thread for this game. */
                if (result){
                    printf("Thread creation failed with return code %d\n", result);
                    exit(-1);
                }

                printf("[DEBUG] New game thread started.\n");



        }

    close(lis_sockfd);

    pthread_mutex_destroy(&mutexcount);
    pthread_exit(NULL);
}


/* Sets up the listener socket. */
int setup_listener(int portno)
{
    int sockfd;
    struct sockaddr_in serv_addr;

    /* Get a socket to listen on */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening listener socket.");

    /* Zero out the memory for the server information */
    memset(&serv_addr, 0, sizeof(serv_addr));

    /* set up the server info */
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    /* Bind the server info to the listener socket. */
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR binding listener socket.");

    //printf("[DEBUG] Listener set.\n");

    /* Return the socket number. */
    return sockfd;
}


/* Sets up the client sockets and client connections. */
void get_clients(int lis_sockfd, int * cli_sockfd)
{
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;

    /* Listen for clients. */
    listen(lis_sockfd, 253 - player_count);

    /* Zero out memory for the client information. */
    memset(&cli_addr, 0, sizeof(cli_addr));

    clilen = sizeof(cli_addr);

    /* Accept the connection from the client. */
    cli_sockfd[num_conn] = accept(lis_sockfd, (struct sockaddr *) &cli_addr, &clilen);

    if (cli_sockfd[num_conn] < 0)
    /* Horrible things have happened. */
        error("ERROR accepting a connection from a client.");

    /* Send the client it's ID. */
    write(cli_sockfd[num_conn], &num_conn, sizeof(int));


    /* Authentication Process */
    bool isauthenticated = authenticate_process(*cli_sockfd);
    if (isauthenticated){
        printf("Authenticated\n");
    }
    else {
        printf("Not Authenticated\n");
    }

    /* Increment the player count. */
    num_conn++;
    pthread_mutex_lock(&mutexcount);
    player_count++;

    printf("Number of players is now %d.\n", player_count);
    pthread_mutex_unlock(&mutexcount);

}

/* Runs a game clients. */
void *menu_option(void *thread_data)
{
    int *cli_sockfd = (int*)thread_data; /* Client sockets. */
    int gameoption = 0;
    while(1){
        gameoption = recv_int(*cli_sockfd);
        printf("[DEBUG] User menu option: %d\n",gameoption);
        while (gameoption == 1){
            running_game(*cli_sockfd); // Run Game Logic
            break;
        }
        while (gameoption == 2){
            show_leaderboard(*cli_sockfd);
            // Need to notify client to break and send menu option again
            break;
        }
    }


    printf("\nGame over.\n");

    close(*cli_sockfd);


    free(cli_sockfd);

    pthread_exit(NULL);
}

0 个答案:

没有答案