Visit The New, Modern Unix Linux Community


I am a little bit confused in a socket example through select()


 
Thread Tools Search this Thread
Top Forums Programming I am a little bit confused in a socket example through select()
# 1  
I am a little bit confused in a socket example through select()

Hi, I am a newbie about network programming. All codes come from this book: UNIX Network Programming Volume 1, Third Edition.

It is a TCP server by use select()
Code:
  int main(int argc, char **argv) {
      int                    i, maxi, maxfd, listenfd, connfd, sockfd;
      int                    nready, client[FD_SETSIZE];
      ssize_t                n;
      fd_set                rset, allset;
      char                buf[MAXLINE];
      socklen_t            clilen;
      struct sockaddr_in    cliaddr, servaddr;
  
      listenfd = Socket(AF_INET, SOCK_STREAM, 0);
  
      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family      = AF_INET;
      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
      servaddr.sin_port        = htons(SERV_PORT);
  
      Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
  
      Listen(listenfd, LISTENQ);
  
      maxfd = listenfd;            /* initialize */
      maxi = -1;                    /* index into client[] array */
      for (i = 0; i < FD_SETSIZE; i++)
          client[i] = -1;            /* -1 indicates available entry */
      FD_ZERO(&allset);
      FD_SET(listenfd, &allset);
  
      for ( ; ; ) {
          rset = allset;        /* structure assignment */
          nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
  
          if (FD_ISSET(listenfd, &rset)) {    /* new client connection */
              clilen = sizeof(cliaddr);
              connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
  
              for (i = 0; i < FD_SETSIZE; i++)
                  if (client[i] < 0) {
                      client[i] = connfd;    /* save descriptor */
                      break;
                  }
              if (i == FD_SETSIZE)
                  err_quit("too many clients");
  
              FD_SET(connfd, &allset);    /* add new descriptor to set */
              if (connfd > maxfd)
                  maxfd = connfd;            /* for select */
              if (i > maxi)
                  maxi = i;                /* max index in client[] array */
  
              if (--nready <= 0)
                  continue;                /* no more readable descriptors */
          }
  
          for (i = 0; i <= maxi; i++) {    /* check all clients for data */
              if ( (sockfd = client[i]) < 0)
                  continue;
              if (FD_ISSET(sockfd, &rset)) {
                if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
                        /*4connection closed by client */
                    Close(sockfd);
                    FD_CLR(sockfd, &allset);
                    client[i] = -1;
                } else
                    Writen(sockfd, buf, n);
  
                  if (--nready <= 0)
                      break;                /* no more readable descriptors */
              }
          }
      }
  }

Please focus on the highlighted section, There are Read(), Writen() functions, the context of them are shown below:
Code:
  ssize_t Read(int fd, void *ptr, size_t nbytes) {
      ssize_t        n;
      if ( (n = read(fd, ptr, nbytes)) == -1)
          err_sys("read error");
      return(n);
  }
  
  void Writen(int fd, void *ptr, size_t nbytes) {
      if (writen(fd, ptr, nbytes) != nbytes)
          err_sys("writen error");
  }
  
  void err_sys(const char *fmt, ...) {
      va_list        ap;
      va_start(ap, fmt);
      err_doit(1, LOG_ERR, fmt, ap);
      va_end(ap);
      exit(1);
  }

Why the TCP server once received a read error [the Read() function has exit()], then exit the program? It will happen when a client is sending data and shutdown abnormally.
The same problem with writen().

Is it possible to change the codes like this? Then any disadvantage about modified codes?
Code:
              if (FD_ISSET(sockfd, &rset)) {
                if ( (n = Read(sockfd, buf, MAXLINE)) <= 0) {
                        /*4connection closed by client */
                      if ( n == 0 ) {
                       puts( "Client hung up!" );
                    } else {
                       puts( "Read error!" );
                    }
                    Close the socket when error or hung up.
                    Close(sockfd);
                    FD_CLR(sockfd, &allset);
                    client[i] = -1;
                } else
                    Writen(sockfd, buf, n);
  
  ssize_t Read(int fd, void *ptr, size_t nbytes) {
       ssize_t        n;
       if ( (n = read(fd, ptr, nbytes)) == -1)
           puts("read error");
       return(n);
   }
   
   void Writen(int fd, void *ptr, size_t nbytes) {
       if (writen(fd, ptr, nbytes) != nbytes)
           puts("writen error");
   }

Thank you for your help!
# 2  
To be honest, I do not really understand your question.
What exactly is the problem?

Just a quick thing about your code changes: They would not change anything except for the puts().
read() returns either -1 on error or the number of bytes read. The -1 case will call err_sys which will exit the whole program. So Read() will always return something >= 0
# 3  
Quote:
Originally Posted by disaster
To be honest, I do not really understand your question.
What exactly is the problem?

Just a quick thing about your code changes: They would not change anything except for the puts().
read() returns either -1 on error or the number of bytes read. The -1 case will call err_sys which will exit the whole program. So Read() will always return something >= 0
Hi, I hope the TCP server never stop or exit anytime. In the original one, the TCP server exits once any read error occur, it is horrible since clients may hung up during the transmission and it is nondeterministic.
So I change a little bit about the codes and deduct exit() functions. However, I am not sure whether these changes affect select() method or not. So it is the question I want to ask.

Thanks.

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #43
Difficulty: Easy
A serial interface transmits two bits of information at the same time, both a one and a zero.
True or False?

8 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Is this sort working as it is supposed to be? A bit confused whether it is sorting correctly or not

Hi, Below is the sample file: $ cat x.txt MDSYS|OGIS_GEOMETRY_COLUMNS|TABLE MDSYS|OGIS_SPATIAL_REFERENCE_SYSTEMS|TABLE MDSYS|SDO_IDX_TAB_SEQUENCE|SEQUENCE MDSYS|SDO_PREFERRED_OPS_USER|TABLE MDSYS|SDO_ST_TOLERANCE|TABLE MDSYS|SDO_TOPO_DATA$|TABLE MDSYS|SDO_TOPO_RELATION_DATA|TABLE... (4 Replies)
Discussion started by: newbie_01
4 Replies

2. Windows & DOS: Issues & Discussions

Which version of Windows Vista to install with a product key? 32-bit or 64-bit?

Hello everyone. I bought a dell laptop (XPS M1330) online which came without a hard drive. There is a Windows Vista Ultimate OEMAct sticker with product key at the bottom case. I checked dell website (here) for this model and it says this model supports both 32 and 64-bit version of Windows... (4 Replies)
Discussion started by: milhan
4 Replies

3. Programming

Socket and select

I have created two sockets and binded both. My requirement is that 2nd socket must send/ recv data only on expiration of timeval(tv). but the 1st socket must keep on send/recv the data without waiting for the 2nd socket completion...... I have posted my code below...... In this code the 2nd... (3 Replies)
Discussion started by: naresh046
3 Replies

4. IP Networking

Clarification - Setting socket options at the same time when socket is listening

I need clarification on whether it is okay to set socket options on a listening socket simultaneously when it is being used in an accept() call? Following is the scenario:- -- Task 1 - is executing in a loop - polling a listen socket, lets call it 'fd', (whose file descriptor is global)... (2 Replies)
Discussion started by: jake24
2 Replies

5. UNIX for Advanced & Expert Users

connect problem for sctp socket (ipv6 socket) - Runtime fail Invalid Arguments

Hi, I was porting ipv4 application to ipv6; i was done with TCP transports. Now i am facing problem with SCTp transport at runtime. To test SCTP transport I am using following server and client socket programs. Server program runs fine, but client program fails giving Invalid Arguments for... (0 Replies)
Discussion started by: chandrutiptur
0 Replies

6. Programming

Multiplexing socket and message queue using Select()

I have a socket and a message queue over which i am trying to multiplex input using select(). When data comes over socket the select works but when it comes over message queue the select is not detecting it . Create_Q gets the identifier of the messege queue. ... (1 Reply)
Discussion started by: shaurya.rastogi
1 Replies

7. Programming

Anyone know how to use socket select() function?

hello socket programming expert, I having difficulties in understanding how select() function in socket programming work.... I'm trying to create my own peer-to-peer chat or file transfer program by using the select() function.... Therefore does anyone had any tutorial or source code that... (4 Replies)
Discussion started by: draggy
4 Replies

8. Programming

copying or concatinating string from 1st bit, leaving 0th bit

Hello, If i have 2 strings str1 and str2, i would like to copy/concatenate str2 to str1, from 1st bit leaving the 0th bit. How do i do it? (2 Replies)
Discussion started by: jazz
2 Replies

Featured Tech Videos