让recv()仅接受先前接受的套接字

问题描述 投票:0回答:1

我正在使用此服务器应用程序:

enter image description here

我想在FD_ISSET()之前向recv()添加一些条件:

if (`client's socket` was the previous `accepted socket`) {
    canRecv = TRUE;
} else {
    canRecv = FALSE;
}

这是我对程序功能的想法:

  1. [recv仅来自先前的accepted socket
  2. 等待通信结束
  3. FD_CLR()

我不知道如何:

  1. select()循环遍历每个fd
  2. 只让一个recv()
  3. 将其他人返回到select()的队列

我使用来自IBM知识中心的简单示例:

https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzab6/xnonblock.htm

c++ sockets
1个回答
0
投票

您可以创建一个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
        }
    }

© www.soinside.com 2019 - 2024. All rights reserved.