2012-10-28 26 views
2

我有这个简单的服务器,5个客户端可以连接到。现在的问题是,我该如何决定谁现在正在说话? 它适用于一个客户端,因为它使用相同的i进行读取和发送。当有2个客户端连接时,我想发送一些与发送该消息的客户端相关联的唯一ID,以便在下次发送消息时,ID应该与珍贵消息的ID相同。哪位客户正在交谈?

连接,发送和接收完成的服务器代码的小片段。

while (true) 
    { 
    this->readingSockets = this->openSockets; 
    this->socketBind = select(getdtablesize(), &this->readingSockets, NULL, NULL, (struct timeval *)NULL); 
    if (FD_ISSET(sD, &this->readingSockets)) 
     { 
      cD = accept(sD, (struct sockaddr *)&this->clientAdr,(socklen_t*) &this->sCadr); 
      FD_SET(cD, &this->openSockets); 
      continue; 
     } 

for (int i=0; i<getdtablesize(); i++) 
     if (i != sD && FD_ISSET(i, &this->readingSockets)) 
      { 
       this->socketBind = read(i, this->buf, sizeof(buf)); 
       g1.cast(buf,id);//where i'd like to send that unique id 
       if (this->socketBind == 0) 
       { 
        FD_CLR(i, &this->openSockets); 
        close(i); 
       } 
       else 
       { 
        send(i,g1.getA(),g1.getSize(),0); 
        g1.setMsg(c); 
       } 
      } 
    } 

此致敬意。

+8

向导客户端正在监听... –

+0

你确定你的循环是正确的吗?你是不是将循环计数器与文件描述符混合? –

+1

@j_random_hacker,你必须进入万圣节的精神! –

回答

2

您知道五个客户端中的每一个都有自己的文件描述符连接(因为您已分别接受每个连接),因此您可以通过跟踪文件描述符来分析您正在与之通话的客户端与...合作。对于客户端的标识,您可以使用getpeername()来查找对等名称,它使用套接字文件描述符和地址结构。

如我所见,唯一一次这可能会变得麻烦的是,如果套接字是由一个进程建立的,那么进程会分叉并且多个进程最终使用该套接字。

+0

好的......但是当我读到getpeername()时,它说如果成功则返回0,否则返回-1,我不明白这怎么能帮助我识别客户端。你可以给我看一些代码吗? – ogward

+0

这取决于你'识别客户'的含义。 'getpeername()'函数告诉你另一端的进程的IP地址(但这是关于所有的)。如果你需要知道它是哪个程序(它可能是五个不同的可执行文件之一),并且不能保证该进程将是本地的(它可能运行在世界另一端的另一台机器上),那么你需要一个协议,以便客户向你表明自己。当然,任何Python脚本都可以发送类似的标识,因此您不应仅根据客户的说法授权操作。 –

+0

我的描述很不清楚。这只会用于本地主机。我希望每当客户端连接一个ID分配给他(或类似的),所以每当他发送一条消息,我可以使用该ID,并将其发送到我已经做的一个小游戏。该id只是为了区分客户。 – ogward

1

建立某种形式的结构:

struct GameClient 
{ 
    int socket; 
    char ip_address[30]; 
    int user_id; 
    //etc 
}; 

保持这些连接的std::map

std::map<int, GameClient> current_clients; 

当你从插座sock_fd读书,刚刚得到的信息:

GameClient* current_client = &current_clients[sock_fd]; 

当客户端断开连接时:

current_clients.erase(sock_fd);