1

方案:当在一个插座中选择“检测活动”时,我的代码中会发生以下标准。

伪代码:

after select i am checking in
if stdin f descriptor
    do something

else if listening file descriptor
newFDescriptor = accept sockFDescriptor, (struct sockaddr *) &clientAddress, &clientAddressSize

FD_SET (new file descriptor)
send connected response to peer

// data from connected peer
else {
    receive data
}

但是每次我从一个对等点向另一个点发送一些东西时,它都会与新的文件描述符创建新的连接。即它不能识别已为该对等点创建的文件描述符中的数据。对等体 1 到对等体 2(创建新文件描述符) 对等体 1 到对等体 2(再次新连接) 它正在接收侦听文件描述符上的所有数据。

4

2 回答 2

1

如果对等方坚持要创建新连接,那么在服务器端您将无能为力。

“它正在接收侦听文件描述符上的所有数据”并没有意义。不可能。监听文件描述符除了接受连接之外什么都做不了。

于 2013-09-27T03:45:04.727 回答
0

我同意 jedwards (+1)——你应该阅读 Beej 的指南来帮助你入门。

同时,这里有一些快速输入可能有助于避免您遇到的错误。我的猜测是您正在混淆文件描述符。

您需要将新的文件描述符(来自 accept() 调用的那些)添加到列表中,然后(也)使用它们来填充 fd 集以供下一次 select 调用。侦听器 fd 仅用于建立新连接和后续的 accept() ——您不应该在该 fd 上调用接收或发送(我们称之为 server_fd)。

这是一个将所有连接存储在数组中的快速示例代码,然后您可以按如下方式设置 fd。对于没有有效 fd 的数组索引,它使用 -1。

FD_ZERO(&read_fd_set);
/* Set the fd_set before passing it to the select call */
for (i=0;i < MAX_CONNECTIONS;i++) {
   if (all_connections[i] >= 0) {
       FD_SET(all_connections[i], &read_fd_set);
   }
}

ret_val = select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL);

一旦选择返回,您可以检查带有读取事件的 fd 是否是服务器 fd,如果是,您可以调用 accept() 来获取新的 fd——您需要将其添加到数组中。像这样的东西:

if (FD_ISSET(server_fd, &read_fd_set)) { 
    new_fd = accept(server_fd, (struct sockaddr*)&new_addr, &addrlen);
    if (new_fd >= 0) {
        printf("Accepted a new connection with fd: %d\n", new_fd);
        for (i=0;i < MAX_CONNECTIONS;i++) {
             if (all_connections[i] < 0) {
                 all_connections[i] = new_fd; 
                 break;
             }
        }
    }
} 
于 2013-09-27T03:34:36.447 回答