2013-01-24 69 views
0

我真的有麻烦,接受多个客户端到Socket服务器。 目前,允许一个客户端。当下一个客户端尝试加入时,该应用会冻结并且什么也不做。C++ - 接受多个客户端

上周我已经做了大量的研究,但没有任何东西能满足我。 我看过关于多线程的教程,但是我没有给出足够的关于函数的信息来实际使用它(是的,我是一个非常直观的学习者,这不是编程的最佳选择)。

所以我只是想知道如果我能得到一个体面的如何做到这一点很好的解释。 如果可能的话,甚至可能会抛出一个例子。

我也看到这个select()函数,其中我也没有提供足够的信息。

虽然我确实有一个运行和工作的服务器,但多线程真的开始搅乱我的头脑,我对这种情况以及它的工作方式感到非常困惑。

所以如果我能给出一个解释和例子,那会很棒!

这是我目前的服务器代码,我将如何启用多个客户端?

#include <iostream> 
#include <winsock2.h> 
#include <vector> 

bool gamerunning = true; 
bool srvr_connect = false; 
int srvr_rec = 0; 

int main() { 
    WSAData wsa; 
    WORD Version = MAKEWORD(2, 1); 

    WSAStartup(Version, &wsa); 

    SOCKET Listen; 
    SOCKET Connect; 

    Listen = socket(AF_INET, SOCK_STREAM, 0); 
    Connect = socket(AF_INET, SOCK_STREAM, 0); 

    SOCKADDR_IN Server; 

    Server.sin_addr.s_addr = inet_addr("192.168.2.4"); 
    Server.sin_family = AF_INET; 
    Server.sin_port = htons(100); 

    bind(Listen, (SOCKADDR*)&Server, sizeof(Server)); 

    listen(Listen, 4); 

    int size = sizeof(Server); 

    std::cout << "Your server has been started!\nConnecting...\n"; 

    Connect = accept(Listen, (SOCKADDR*)&Server, &size); 

    while (gamerunning) { 
     if (Connect != NULL) { 
      srvr_connect = true; 
      std::cout << "Welcome to player: " << srvr_rec << "\n"; 
      srvr_rec +=1; 
     } 
     if (srvr_connect == true) { 
      if (test_frame == 0) { 
       std::cout << "Connection Sent!\nConnection Has Been Breached!\nPlayers Are Now Able to Join Your Server!\n"; 
       test_frame +=1; 
      } 
     } 
    } 
    std::cin.get(); 
    return 0; 
} 

正如您所看到的,这对我的客户非常有用。但只接受一个。 我该如何解决这个问题?

+3

单线程'基于select'服务器应该是你的第一步。它在概念上很简单,对于培训目的来说也是合理的。 –

+0

@KerrekSB这对于生产目的来说是相当强大的... Nginx ... –

+1

你写的那种网络代码有效吗? –

回答

0
// define a list of sockets 
// create the socket you are going to accept on and add the socket to the list 
while(true) { 
    // use the list to build the read set 
    select(.. read-set ..) 
    for(all sockets in the read-set) { 
     if(socket == accept-socket) { 
       // do accept 
       // add the new socket to the list 
     } else { 
       // read data from the socket 
     } 
    } 
} 

你可以使用select()这样的

fd_set readfds; 
fd_set writefds; 
fd_set exceptfds; 
FD_ZERO(readfds); 
FD_ZERO(writefds); 
FD_ZERO(exceptfds); 
int nfds = 0; 
for(all socket x in socket list) { 
    FD_SET(x, readfds) 
    nfds++; 
} 
int rc = select(nfds, & readfds, & writefds, & exceptfds, 0); 
for(all socket x in socket list) { 
    if(FD_ISSET(x, readfds)) { 
     // socket x has something to read or accept 
    } 
} 
+0

好吧,在我将它添加到我的代码之前,这是如何工作的?例如,这个“循环”(或者任何你想要调用它的)套接字是如何的? “ – user2009320

+0

”当我将其改为“fd_set * readfds”时,无法将'readfds'从'fd_set'类型转换为键入'fd_set *'“,然后在'select'中将'fd_set **'更改为'fd_set' – user2009320

+0

我上面发布了我的代码。你能帮忙吗? – user2009320