Non-blocking I/O

 

 

ü Non-blocking Read/Write

ü Non-blocking Connect

ü Non-blocking Accept

 

 



êNon-blocking Read/Write:

ü To set a socket (or any fd) to  non-blocking:

        val = fcntl (fd, F_GETFL, 0);

        fcntl (fd, F_SETFL, val | O_NONBLOCK);

ü To read  from fd  we use:

       

       if ( (n = read (fd, buffer, buffer_lenght)) < 0) {
             if (errno != EWOULDBLOCK)
             perror ("read error from fd");
   }
 

ü To write to fd  we use:

       

      if ( (n = write (fd, buffer, buffer_lenght)) < 0) {
                if (errno != EWOULDBLOCK)
                perror ("write error to fd");
      }

Examples:

        nonblockRead.c

% nonblockRead 5

nonblockWrite.c

% nonblockWrite 5

ChatClientNonBlock.c

% ChatClientNonBlock <host> <port>  

 

 




 

ê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    &   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 

Earlier versions of Solaris causes the server to hang when a client send RST immediately after connect.