场景:当在一个套接字中选择检测活动时,我的代码中会出现以下条件。
伪代码:
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
}
但是每次我从对等端向其他人发送内容时,它会与新的filedescriptor建立新的连接。即,它不会对已创建的此对等方的文件描述符中的数据进行重新识别。 peer 1 to peer 2(创建新文件描述符) 对等1对等2(再次新连接) 它正在接收侦听文件描述符上的所有数据。
答案 0 :(得分:1)
如果对等方坚持创建新连接,那么在服务器端无法对此进行任何操作。
“它正在接收关于侦听文件描述符的所有数据”并没有开始有意义。不可能。除了接受连接之外,侦听文件描述符不能执行任何操作。
答案 1 :(得分:0)
我同意jedwards(+1) - 您应该阅读Beej指南以帮助您入门。
同时,这里有一些快速输入可能有助于避免您遇到的错误。我的猜测是你混淆了文件描述符。
您需要将新文件描述符(来自accept()调用的描述符)添加到列表中,然后使用它们(也)填充下一个select调用的fd set。监听器fd仅用于建立新连接和后续accept() - 您不应该在该fd上调用receive或send(让我们称之为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);
一旦select返回,你可以检查带有read-event的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;
}
}
}
}