有人可以用WinSock解释可写和可读fd_sets的功能吗?

时间:2015-11-30 22:08:42

标签: c++ select winsock

我正在为大学项目编写网络游戏,虽然我在客户端和服务器之间发送和接收消息,但我不确定如何实现writeable fd_set(我的讲师的示例代码仅包含readable fd_set)以及fd_sets与select()的函数。你能给出的任何见解都会很好地帮助我理解这一点。

我的服务器代码是这样的:

bool ServerSocket::Update() {
    // Update the connections with the server

    fd_set readable;
    FD_ZERO(&readable);

    // Add server socket, which will be readable if there's a new connection
    FD_SET(m_socket, &readable);

    // Add connected clients' sockets
    if(!AddConnectedClients(&readable)) {
        Error("Couldn't add connected clients to fd_set.");
        return false;
    }

    // Set timeout to wait for something to happen (0.5 seconds)
    timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 500000;

    // Wait for the socket to become readable
    int count = select(0, &readable, NULL, NULL, &timeout);
    if(count == SOCKET_ERROR) {
        Error("Select failed, socket error.");
        return false;
    }

    // Accept new connection to the server socket if readable
    if(FD_ISSET(m_socket, &readable)) {
        if(!AddNewClient()) {
            return false;
        }
    }

    // Check all clients to see if there are messages to be read
    if(!CheckClients(&readable)) {
        return false;
    }

    return true;
}

3 个答案:

答案 0 :(得分:3)

您要创建一个名为a = 3.0000 4.5000 6.0000 5.5000 5.0000 4.5000 4.0000 的{​​{1}}变量,以相同的方式初始化它(使用相同的套接字),并将其作为fd_set传递给第三个参数:

writeable

然后在select返回后,检查每个套接字是否仍在集select(0, &readable, &writeable, NULL, &timeout); 中。如果是这样,那么它是可写的。

基本上,select的工作方式完全相同,只是它告诉你关于套接字的不同之处。

答案 1 :(得分:2)

套接字变为:

  • 如果套接字接收缓冲区中有数据或待处理的FIN(recv()即将返回零),则可读;
  • 如果套接字接收缓冲区中有空间,则
  • 可写。请注意,几乎所有时间都是如此,因此只有在套接字上遇到先前的EWOULDBLOCK / EAGAIN时才应该使用它,并在不使用时停止使用它。

答案 2 :(得分:-2)

select()非常过时,它的界面很神秘。 poll(或者它的Windows对应WSAPoll是它的现代替代品,应该始终是首选。

它将以下列方式使用:

WSAPOLLFD pollfd = {m_socket, POLLWRNORM, 0};
int rc = WSAPoll(&pollfd, 1, 100);
if (rc == 1) {
   // Socket is ready for writing!
}