Vraag Hoe kan ik een socket terugzetten naar de blokkeermodus (nadat ik deze heb ingesteld op de niet-blokkerende modus)?


Ik heb dit gelezen met betrekking tot het instellen van een socket naar niet-blokkerende modus.

http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags

Dit is wat ik deed:

static void setnonblocking(int sock)
{
    int opts;

    opts = fcntl(sock,F_GETFL);
    if (opts < 0) {
        perror("fcntl(F_GETFL)");
        exit(EXIT_FAILURE);
    }
    opts = (opts | O_NONBLOCK);
    if (fcntl(sock,F_SETFL,opts) < 0) {
        perror("fcntl(F_SETFL)");
        exit(EXIT_FAILURE);
    }
    return;
}

Hoe kan ik de socket terugzetten naar de blokkeermodus? Ik zie geen O_BLOCK-vlag?

Dank je.


12
2018-01-27 19:47


oorsprong


antwoorden:


Heb je geprobeerd de O_NONBLOCK-vlag te wissen?

opts = opts & (~O_NONBLOCK)

14
2018-01-27 19:53



Hier is een meer geschikt platform voor meerdere platformen:

bool set_blocking_mode(const int &socket, bool is_blocking)
{
    bool ret = true;

#ifdef WIN32
    /// @note windows sockets are created in blocking mode by default
    // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated
    u_long non_blocking = is_blocking ? 0 : 1;
    ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &non_blocking);
#else
    const int flags = fcntl(socket, F_GETFL, 0);
    if ((flags & O_NONBLOCK) && !is_blocking) { info("set_blocking_mode(): socket was already in non-blocking mode"); return ret; }
    if (!(flags & O_NONBLOCK) && is_blocking) { info("set_blocking_mode(): socket was already in blocking mode"); return ret; }
    ret = 0 == fcntl(socket, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags | O_NONBLOCK));
#endif

    return ret;
}

5
2017-10-12 18:45



Alternatieve manier om de vlag te wissen:

opts ^= O_NONBLOCK;

Hierdoor wordt de niet-blokkerende vlag geschakeld, d.w.z. schakel niet-blokkering uit als deze momenteel is ingeschakeld.


0
2018-01-27 23:00