我正在使用此服务器应用程序:
我想在FD_ISSET()
之前向recv()
添加一些条件:
if (`client's socket` was the previous `accepted socket`) {
canRecv = TRUE;
} else {
canRecv = FALSE;
}
这是我对程序功能的想法:
recv
仅来自先前的accepted socket
我不知道如何:
select()
循环遍历每个fdrecv()
select()
的队列我使用来自IBM知识中心的简单示例:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzab6/xnonblock.htm
您可以创建一个std::vector<int> sockets;
来保留套接字。然后,只需检查if(current_socket == sockets[sockets.size()-1]) ...
这是一个带有帮助器类的示例,用于保留套接字和函数列表以等待活动。
#include <cerrno>
#include <cstring>
#include <utility>
#include <vector>
constexpr unsigned other_socket = 0;
constexpr unsigned server_socket = 0;
constexpr unsigned latest_addition = 0;
class SocketList {
public:
explicit SocketList(int server) {
add(server);
}
void add(int s) {
sockets.push_back(s);
FD_SET(s, &readfds);
if(s > max_fd) max_fd = s;
}
// return the ready sockets and a state for each
std::vector<std::pair<int, unsigned>> wait() {
int ready_sockets;
do {
ready_sockets = select(max_fd + 1, &readfds, nullptr, nullptr, nullptr);
} while(ready_sockets == -1 && errno == EINTR); // retry if it was interrupted
// throw if an error occured
if(ready_sockets == -1) throw std::runtime_error(std::strerror(errno));
std::vector<std::pair<int, unsigned>> result;
for(int s : sockets) {
if(FD_ISSET(s, &readfds)) {
auto x = other_socket;
if(s == sockets[0]) x |= server_socket;
if(s == sockets[sockets.size() - 1]) x |= latest_addition;
result.emplace_back(s, x);
}
}
return result;
}
private:
int max_fd = 0;
fd_set readfds;
std::vector<int> sockets;
};
可以这样使用:
int server_socket = socket(...);
SocketList ss(server_socket);
auto result = ss.wait();
for(auto [socket, state] : result) {
if(state & server_socket) {
/* do server things */
} else if(state & latest_addition) {
/* do stuff if it was the latest addition */
} else {
/* do this to the other sockets
}
}