0

I'm writing a network game for a university project and while I have messages being sent and received between a client and a server, I'm unsure on how I would go about implementing a writeable fd_set (my lecturer's example code only included a readable fd_set) and what the function is of both fd_sets with select(). Any insight you could give would be great in helping me understand this.

My server code is as such:

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;
}
DeanoMachino
  • 59
  • 2
  • 12

3 Answers3

3

A socket becomes:

  • readable if there is either data in the socket receive buffer or a pending FIN (recv() is about to return zero)
  • writable if there is room in the socket receive buffer. Note that this is true nearly all the time, so you should use it only when you've encountered a prior EWOULDBLOCK/EAGAIN on the socket, and stop using it when you don't.
user207421
  • 305,947
  • 44
  • 307
  • 483
  • Well, this DOES NOT answer OP question. OP did not ask what it means for a socket to be writable, OP asks on how to poll for writable state. It is also terribly wrong to say 'socket is writable all the time'. Apparently, you've never dealt with fast producer/slow consumer cases. – SergeyA Nov 30 '15 at 22:21
  • 2
    @Sergey OP asked precisely that, and I did not utter the misquotation you have fabricated from my words. I refer you to the title of the question, repeated in the text, *viz* 'Can someone explain the function of writeable and readable fd_sets', and to what I actually wrote. – user207421 Dec 01 '15 at 03:54
3

You'd create an fd_set variable called writeable, initialize it the same way (with the same sockets), and pass it as select's third argument:

select(0, &readable, &writeable, NULL, &timeout);

Then after select returns you'd check whether each socket is still in the set writeable. If so, then it's writeable.

Basically, exactly the same way readable works, except that it tells you a different thing about the socket.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • That makes a lot of sense to me. What I'm not understanding entirely is why I would need to find out whether the socket is writeable. Would it be whenever I'm sending a message that I would need to check if it was writeable? – DeanoMachino Nov 30 '15 at 22:29
  • @DeanoMachino `send` can block, just like `recv`. So, similar reasons to why you'd want to find out if a socket is readable - it's just less important since `send` blocks less often than `recv`. – user253751 Nov 30 '15 at 22:36
-3

select() is terribly outdated and it's interface is arcane. poll (or it's windows counterpart WSAPoll is a modern replacement for it, and should be always preferred.

It would be used in following manner:

WSAPOLLFD pollfd = {m_socket, POLLWRNORM, 0};
int rc = WSAPoll(&pollfd, 1, 100);
if (rc == 1) {
   // Socket is ready for writing!
}
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 2
    Doesn't answer the question in any way. – user207421 Nov 30 '15 at 22:20
  • @EJP, how so? It perfectly tells OP how to poll for the writable socket, and directs OP to a proper function. Fail to see how it 'does not answer the question'. – SergeyA Nov 30 '15 at 22:20
  • The question was 'can somebody explain the function of writeable and readable fd_sets'. You've explained nothing here. – user207421 Dec 24 '15 at 03:54