How do I change a TCP socket to be non-blocking?

Viewed 192474

How do you make a socket non-blocking?

I am aware of the fcntl() function, but I've heard it's not always reliable.

10 Answers

On Linux and BSD you can directly create the socket in non-blocking mode (https://www.man7.org/linux/man-pages/man7/socket.7.html):

int fd = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK | SOCK_CLOEXEC, res->ai_protocol);
if (fd == -1) {
    perror("socket");
    return -1;
}

When accepting connections you can use the accept4 function to directly accept new connections in non-blocking mode (https://man7.org/linux/man-pages/man2/accept.2.html):

int fd = accept4(lfd, NULL, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (fd == -1) {
    perror("accept4");
    return -1;
}

I don't know why the accepted answer doesn't mention this.

I know it's an old question, but for everyone on google ending up here looking for information on how to deal with blocking and non-blocking sockets here is an in depth explanation of the different ways how to deal with the I/O modes of sockets - http://dwise1.net/pgm/sockets/blocking.html.

Quick summary:

  • So Why do Sockets Block?

  • What are the Basic Programming Techniques for Dealing with Blocking Sockets?

    • Have a design that doesn't care about blocking
    • Using select
    • Using non-blocking sockets.
    • Using multithreading or multitasking

If you want to change socket to non blocking , precisely accept() to NON-Blocking state then

    int flags=fcntl(master_socket, F_GETFL);
        fcntl(master_socket, F_SETFL,flags| O_NONBLOCK); /* Change the socket into non-blocking state  F_SETFL is a command saying set flag and flag is 0_NONBLOCK     */                                          

while(1){
    if((newSocket = accept(master_socket, (struct sockaddr *) &address, &addr_size))<0){
                if(errno==EWOULDBLOCK){
                       puts("\n No clients currently available............ \n");
                       continue;
               }
    }else{
          puts("\nClient approched............ \n");
    }

}

It is sometimes convenient to employ the "send/recv" family of system calls. If the flags parameter contains the MSG_DONTWAIT flag, each call will behave similar to a socket having the O_NONBLOCK flag set.

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
Related