【问题标题】:Handling multiple clients for game server为游戏服务器处理多个客户端
【发布时间】:2015-05-23 08:46:39
【问题描述】:

我无法弄清楚如何在不阻塞服务器的情况下存储客户端句柄。我正在关注 Stevens 在“The Socket Networking API”中详述的并发服务器模型。

我的程序在玩家之间创建井字游戏。

程序的结构是这样的:服务器处理 TCP/UDP 连接。客户端程序可以查询或连接到服务器。如果客户端查询,UDP 套接字通过返回已连接客户端的句柄列表来处理查询。

如果客户端连接,TCP 套接字通过以下方式处理连接: 1. 向客户端请求句柄和 2. 存储它们的句柄。如果有两个连接的客户端,则会生成一个单独的进程以在它们之间创建匹配(但这现在不相关)。

在我的程序中,我将 TCP/UDP 套接字与select() 复用。我当前的问题是如何在不阻塞的情况下处理询问和存储客户端句柄。

我考虑过:

  1. 创建另一个线程来处理请求和接收客户端句柄。
  2. 保留已连接客户端套接字的列表,并将它们添加到 fd_set 数据结构中,并在它们之间进行多路复用以及 TCP/UDP 套接字。

  3. 产生另一个进程来处理请求/接收句柄,但这不太可能,因为我将句柄存储在全局链表数据结构中,以便服务器可以在查询时返回一个列表。与父母沟通太麻烦了。

*下面的代码还没有经过测试并且不完整,因为我还没有弄清楚如何解决这个问题。

    game_head = NULL; game_tail = game_head;

    /* Creating TCP listening socket */
    tcp_listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(TCP_PORT);
    bind(tcp_listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    listen(tcp_listenfd, LISTENQ);

    /* Creating UDP socket */
    udpfd = socket(AF_INET, SOCK_DGRAM, 0);
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(UDP_PORT);
    bind(udpfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    /* Signal handling (also possibly handle SIGCHLD)*/
    signal(SIGINT, sighandler);
    signal(SIGUSR2, sighandler);

    FD_ZERO(&rset);
    maxfdp1 = max(tcp_listenfd, udpfd) + 1;
    while(1) {
            if (terminate)
                    terminate_program();
            FD_SET(tcp_listenfd, &rset);
            FD_SET(udpfd, &rset);
            if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
                    if (errno == EINTR)
                            continue;
                    else
                            perror("select error");
            }

            if (FD_ISSET(tcp_listenfd, &rset)) {
                    len = sizeof(cliaddr);
                    tcp_connfd = accept(tcp_listenfd, (struct sockaddr *) &cliaddr, &len);
                    close(tcp_connfd);
            }

            if (FD_ISSET(udpfd, &rset)) {

            }
    }

【问题讨论】:

    标签: c tcp network-programming udp multiplexing


    【解决方案1】:

    不要关闭tcp_listenfd。使用一组 TCP 连接器,即tcp_connfd[10] 或其他东西,然后计算您拥有的 TCP 数量。为每个客户分配一个新号码。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      相关资源
      最近更新 更多