Non-blocking I/O

 

 

Ø Non-blocking Read/Write

Ø Non-blocking Connect

Ø Non-blocking Accept

 

 



Ø Non-blocking Read/Write:

 

To set a socket non-blocking:

        val = Fcntl (sockfd, F_GETFL, 0);


        Fcntl (sockfd, F_SETFL, val | O_NONBLOCK);

 

To read  from the socket we use:

        if ( (n = read (sockfd, buffer, buffer_lenght)) < 0) {
                                if (errno != EWOULDBLOCK)
                                        err_sys("read error on socket");
       }
 


 

Ø Non-blocking Connect:

 

    connect_nonb.c

 

     ………………

 

         flags = Fcntl(sockfd, F_GETFL, 0);

          Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

 

 

          if ( (n = connect (sockfd, (struct sockaddr *) saptr, salen)) < 0)

                   if (errno != EINPROGRESS)  return(-1);

 

          /* Do whatever we want while the connect is taking place. */

 

          if (n == 0)  goto done;          /* connect completed immediately */

 

          FD_ZERO(&rset);

          FD_SET(sockfd, &rset);

          wset = rset;

 

          tval.tv_sec = nsec;

          tval.tv_usec = 0;

 

          if ( (n = Select(sockfd+1, &rset, &wset, NULL,  nsec ? &tval : NULL)) == 0) {

                   close(sockfd);              /* timeout */

                    errno = ETIMEDOUT;

                   return(-1);

          }

 

 

Example:

nonbDaytimeClient.c    it uses    tcpDaytimeServer.c

 

tcpDaytimeServer      <port>    <listen-backlog>   <sleep-before-accept>

nonbDaytimeClient    <ip>             <port>             <max-wait-time>

% cd  /home/cs779/stevens3rd.book/unpv13e/nonblock/example

% tcpDaytimeServer       1234             0      25    &
% nonbDaytimeClient    127.0.0.1    1234    0    &     ( gets the time )
% nonbDaytimeClient    127.0.0.1    1234   10   &     ( timeout )
% nonbDaytimeClient    127.0.0.1    1234   50   &     ( gets the time )

  

 



 

Ø Non-blocking Accept:
 

We may use select to achieve non-blocking accept.

 

 

 Example:    tcpservselect03.c 

 

if (FD_ISSET(listenfd, &rset)) {       /* new client connection */
                        printf("listening socket readable\n");
                        clilen = sizeof(cliaddr);
                        connfd = Accept (listenfd, (SA *) &cliaddr, &clilen);

 

 

 Note what will happen when a Client that connects then send RST   (tcpcli03.c)

% tcpcli03 127.0.0.1