allanswers.org - [comp.unix.programmer] Unix-socket-faq for network programming

 Home >  Operational Systemsunix-faq >

[comp.unix.programmer] Unix-socket-faq for network programming

Section 1 of 4 - Prev - Next
All sections - 1 - 2 - 3 - 4


Archive-name: unix-faq/socket
Posting-Frequency: monthly
Last-modified: 1998/01/22
URL: http://www.ibrado.com/sock-faq/

  Programming UNIX Sockets in C - Frequently Asked Questions
  Created by Vic Metcalfe, Andrew Gierth and other con-
  tributers
  January 22, 1998

  This is a list of frequently asked questions, with answers about pro-
  gramming TCP/IP applications in unix with the sockets interface.
  ______________________________________________________________________

  Table of Contents:

  1.      General Information and Concepts

  1.1.    About this FAQ

  1.2.    Who is this FAQ for?

  1.3.    What are Sockets?

  1.4.    How do Sockets Work?

  1.5.    Where can I get source code for the book [book title]?

  1.6.    Where can I get more information?

  2.      Questions regarding both Clients and Servers (TCP/SOCK_STREAM)

  2.1.    How can I tell when a socket is closed on the other end?

  2.2.    What's with the second parameter in bind()?

  2.3.    How do I get the port number for a given service?

  2.4.    If bind() fails, what should I do with the socket descriptor?

  2.5.    How do I properly close a socket?

  2.6.    When should I use shutdown()?

  2.7.    Please explain the TIME_WAIT state.

  2.8.    Why does it take so long to detect that the peer died?

  2.9.    What are the pros/cons of select(), non-blocking I/O and
  SIGIO?

  2.10.   Why do I get EPROTO from read()?

  2.11.   How can I force a socket to send the data in its buffer?

  2.12.   Where can a get a library for programming sockets?

  2.13.   How come select says there is data, but read returns zero?

  2.14.   Whats the difference between select() and poll()?

  2.15.   How do I send [this] over a socket?

  2.16.   How do I use TCP_NODELAY?

  2.17.   What exactly does the Nagle algorithm do?

  2.18.   What is the difference between read() and recv()?

  2.19.   I see that send()/write() can generate SIGPIPE. Is there any
  advantage to handling the signal, rather than just ignoring it and
  checking for the EPIPE error? Are there any useful parameters passed
  to the signal catching function?

  2.20.   After the chroot(), calls to socket() are failing.  Why?

  2.21.   Why do I keep getting EINTR from the socket calls?

  2.22.   When will my application receive SIGPIPE?

  2.23.   What are socket exceptions?  What is out-of-band data?

  2.24.   How can I find the full hostname (FQDN) of the system I'm
  running on?

  3.      Writing Client Applications (TCP/SOCK_STREAM)

  3.1.    How do I convert a string into an internet address?

  3.2.    How can my client work through a firewall/proxy server?

  3.3.    Why does connect() succeed even before my server did an
  accept()?

  3.4.    Why do I sometimes lose a server's address when using more
  than one server?

  3.5.    How can I set the timeout for the connect() system call?

  3.6.    Should I bind() a port number in my client program, or let the
  system choose one for me on the connect() call?

  3.7.    Why do I get "connection refused" when the server isn't
  running?

  3.8.    What does one do when one does not know how much information
  is comming over the socket ? Is there a way to have a dynamic buffer ?

  4.      Writing Server Applications (TCP/SOCK_STREAM)

  4.1.    How come I get "address already in use" from bind()?

  4.2.    Why don't my sockets close?

  4.3.    How can I make my server a daemon?

  4.4.    How can I listen on more than one port at a time?

  4.5.    What exactly does SO_REUSEADDR do?

  4.6.    What exactly does SO_LINGER do?

  4.7.    What exactly does SO_KEEPALIVE do?

  4.8.    How can I bind() to a port number < 1024?

  4.9.    How do I get my server to find out the client's address /
  hostname?

  4.10.   How should I choose a port number for my server?

  4.11.   What is the difference between SO_REUSEADDR and SO_REUSEPORT?

  4.12.   How can I write a multi-homed server?

  4.13.   How can I read only one character at a time?

  4.14.   I'm trying to exec() a program from my server, and attach my
  socket's IO to it, but I'm not getting all the data across.  Why?

  5.      Writing UDP/SOCK_DGRAM applications

  5.1.    When should I use UDP instead of TCP?

  5.2.    What is the difference between "connected" and "unconnected"
  sockets?

  5.3.    Does doing a connect() call affect the receive behaviour of
  the socket?

  5.4.    How can I read ICMP errors from "connected" UDP sockets?

  5.5.    How can I be sure that a UDP message is received?

  5.6.    How can I be sure that UDP messages are received in order?

  5.7.    How often should I re-transmit un-acknowleged messages?

  5.8.    How come only the first part of my datagram is getting
  through?

  5.9.    Why does the socket's buffer fill up sooner than expected?

  6.      Advanced Socket Programming

  6.1.    How would I put my socket in non-blocking mode?

  6.2.    How can I put a timeout on connect()?

  7.      Sample Source Code
  ______________________________________________________________________

  1.  General Information and Concepts

  1.1.  About this FAQ

  This FAQ is maintained by Vic Metcalfe (vic@acm.org), with lots of
  assistance from Andrew Gierth (andrew@erlenstar.demon.co.uk).  I am
  depending on the true wizards to fill in the details, and correct my
  (no doubt) plentiful mistakes.  The code examples in this FAQ are
  written to be easy to follow and understand.  It is up to the reader
  to make them as efficient as required.  I started this faq because
  after reading comp.unix.programmer for a short time, it became evident
  that a FAQ for sockets was needed.

  The FAQ is available at the following locations:

     Usenet: (Posted on the 21st of each month)
        news.answers, comp.answers, comp.unix.answers,
        comp.unix.programmer

     FTP:
        ftp://rtfm.mit.edu/pub/usenet/news.answers/unix-faq/socket

     WWW:
        http://www.ibrado.com/sock-faq
        http://kipper.york.ac.uk/~vic/sock-faq http://www.ntua.gr/sock-
        faq

  Please email me if you would like to correct or clarify an answer.  I
  would also like to hear from you if you would like me to add a
  question to the list.  I may not be able to answer it, but I can add
  it in the hopes that someone else will submit an answer.  Every hour I
  seem to be getting even busier, so if I am slow to respond to your
  email, please be patient.  If more than a week passes you may want to
  send me another one as I often put messages aside for later and then
  forget about them.  I'll have to work on dealing with my mail better,
  but until then feel free to pester me a little bit.

  1.2.  Who is this FAQ for?

  This FAQ is for C programmers in the Unix environment.  It is not
  intended for WinSock programmers, or for Perl, Java, etc.  I have
  nothing against Windows or Perl, but I had to limit the scope of the
  FAQ for the first draft.  In the future, I would really like to
  provide examples for Perl, Java, and maybe others.  For now though I
  will concentrate on correctness and completeness for C.

  This version of the FAQ will only cover sockets of the AF_INET family,
  since this is their most common use.  Coverage of other types of
  sockets may be added later.

  1.3.  What are Sockets?

  Sockets are just like "worm holes" in science fiction.  When things go
  into one end, they (should) come out of the other.  Different kinds of
  sockets have different properties.  Sockets are either connection-
  oriented or connectionless.  Connection-oriented sockets allow for
  data to flow back and forth as needed, while connectionless sockets
  (also known as datagram sockets) allow only one message at a time to
  be transmitted, without an open connection.  There are also different
  socket families.  The two most common are AF_INET for internet
  connections, and AF_UNIX for unix IPC (interprocess communication).
  As stated earlier, this FAQ deals only with AF_INET sockets.

  1.4.  How do Sockets Work?

  The implementation is left up to the vendor of your particular unix,
  but from the point of view of the programmer, connection-oriented
  sockets work a lot like files, or pipes.  The most noticeable
  difference, once you have your file descriptor is that read() or
  write() calls may actually read or write fewer bytes than requested.
  If this happens, then you will have to make a second call for the rest
  of the data.  There are examples of this in the source code that
  accompanies the faq.

  1.5.  Where can I get source code for the book [book title]?

  Here is a list of the places I know to get source code for network
  programming books.  It is very short, so please mail me with any
  others you know of.

  Title: Unix Network Programming
  Author: W. Richard Stevens (rstevens@noao.edu)
  Publisher: Prentice Hall, Inc.
  ISBN: 0-13-949876-1
  URL: http://www.noao.edu/~rstevens

  Title: Power Programming with RPC
  Author: John Bloomer
  Publisher: O'Reilly & Associates, Inc.
  ISBN: 0-937175-77-3
  URL: ftp://ftp.uu.net/published/oreilly/nutshell/rpc/rpc.tar.Z

  Recommended by: Lokmanm Merican (lokmanm#pop4.jaring.my@199.1.1.88)
  Title: UNIX PROGRAM DEVELOPMENT for IBM PC'S Including OSF/Motif
  Author: Thomas Yager
  Publisher: Addison Wesley, 1991
  ISBN: 0-201-57727-5

  1.6.  Where can I get more information?

  I keep a copy of the resources I know of on my socks page on the web.
  I don't remember where I got most of these items, but some day I'll
  check out their sources, and provide ftp information here.  For now,
  you can get them at http://www.ibrado.com/sock-faq.

  There is a good TCP/IP FAQ maintained by George Neville-Neil
  (gnn@wrs.com) which can be found at
  http://www.visi.com/~khayes/tcpipfaq.html

  2.  Questions regarding both Clients and Servers (TCP/SOCK_STREAM)

  2.1.  How can I tell when a socket is closed on the other end?

  From Andrew Gierth (andrew@erlenstar.demon.co.uk):

  AFAIK:

  If the peer calls close() or exits, without having messed with
  SO_LINGER, then our calls to read() should return 0. It is less clear
  what happens to write() calls in this case; I would expect EPIPE, not
  on the next call, but the one after.

  If the peer reboots, or sets l_onoff = 1, l_linger = 0 and then
  closes, then we should get ECONNRESET (eventually) from read(), or
  EPIPE from write().

  I should also point out that when write() returns EPIPE, it also
  raises the SIGPIPE signal - you never see the EPIPE error unless you
  handle or ignore the signal.

  If the peer remains unreachable, we should get some other error.

  I don't think that write() can legitimately return 0.  read() should
  return 0 on receipt of a FIN from the peer, and on all following
  calls.

  So yes, you must expect read() to return 0.

  As an example, suppose you are receiving a file down a TCP link; you
  might handle the return from read() like this:

  rc = read(sock,buf,sizeof(buf));
  if (rc > 0)
  {
      write(file,buf,rc);
      /* error checking on file omitted */
  }
  else if (rc == 0)
  {
      close(file);
      close(sock);
      /* file received successfully */
  }
  else /* rc < 0 */
  {
      /* close file and delete it, since data is not complete
         report error, or whatever */
  }

  2.2.  What's with the second parameter in bind()?

  The man page shows it as "struct sockaddr *my_addr".  The sockaddr
  struct though is just a place holder for the structure it really
  wants.  You have to pass different structures depending on what kind
  of socket you have.  For an AF_INET socket, you need the sockaddr_in
  structure.  It has three fields of interest:

     sin_family
        Set this to AF_INET.

     sin_port
        The network byte-ordered 16 bit port number

     sin_addr
        The host's ip number.  This is a struct in_addr, which contains
        only one field, s_addr which is a u_long.

  2.3.  How do I get the port number for a given service?

  Use the getservbyname() routine.  This will return a pointer to a
  servent structure.  You are interested in the s_port field, which
  contains the port number, with correct byte ordering (so you don't
  need to call htons() on it).  Here is a sample routine:

  /* Take a service name, and a service type, and return a port number.  If the
     service name is not found, it tries it as a decimal number.  The number
     returned is byte ordered for the network. */
  int atoport(char *service, char *proto) {
    int port;
    long int lport;
    struct servent *serv;
    char *errpos;

    /* First try to read it from /etc/services */
    serv = getservbyname(service, proto);
    if (serv != NULL)
      port = serv->s_port;
    else { /* Not in services, maybe a number? */
      lport = strtol(service,&errpos,0);
      if ( (errpos[0] != 0) || (lport < 1) || (lport > 5000) )
        return -1; /* Invalid port address */
      port = htons(lport);
    }
    return port;
  }

  2.4.  If bind() fails, what should I do with the socket descriptor?

  If you are exiting, I have been assured by Andrew that all unixes will
  close open file descriptors on exit.  If you are not exiting though,
  you can just close it with a regular close() call.

  2.5.  How do I properly close a socket?

  This question is usually asked by people who try close(), because they
  have seen that that is what they are supposed to do, and then run
  netstat and see that their socket is still active.  Yes, close() is
  the correct method.  To read about the TIME_WAIT state, and why it is
  important, refer to ``2.7 Please explain the TIME_WAIT state.''.

  2.6.  When should I use shutdown()?

  From Michael Hunter (mphunter@qnx.com):

  shutdown() is useful for deliniating when you are done providing a
  request to a server using TCP.  A typical use is to send a request to
  a server followed by a shutdown().  The server will read your request
  followed by an EOF (read of 0 on most unix implementations).  This
  tells the server that it has your full request.  You then go read
  blocked on the socket.  The server will process your request and send
  the necessary data back to you followed by a close.  When you have
  finished reading all of the response to your request you will read an
  EOF thus signifying that you have the whole response.  It should be
  noted the TTCP (TCP for Transactions -- see R. Steven's home page)
  provides for a better method of tcp transaction management.

  S.Degtyarev (deg@sunsr.inp.nsk.su) wrote a nice in-depth message to me
  about this.  He shows a practical example of using shutdown() to aid
  in synchronization of client processes when one is the "reader"
  process, and the other is the "writer" process.  A portion of his
  message follows:

  Sockets are very similar to pipes in the way they are used for data
  transfer and client/server transactions, but not like pipes they are
  bidirectional.  Programs that use sockets often fork() and each
  process inherits the socket descriptor.  In pipe based programs it is
  strictly recommended to close all the pipe ends that are not used to
  convert the pipe line to one-directional data stream to avoid data
  losses and deadlocks.  With the socket there is no way to allow one
  process only to send data and the other only to receive so you should
  always keep in mind the consequences.

  Generally the difference between close() and shutdown() is: close()
  closes the socket id for the process but the connection is still
  opened if another process shares this socket id.  The connection stays
  opened both for read and write, and sometimes this is very important.
  shutdown() breaks the connection for all processes sharing the socket
  id.  Those who try to read will detect EOF, and those who try to write
  will reseive SIGPIPE, possibly delayed while the kernel socket buffer
  will be filled.  Additionally, shutdown() has a second argument which
  denotes how to close the connection: 0 means to disable further
  reading, 1 to disable writing and 2 disables both.

  The quick example below is a fragment of a very simple client process.
  After establishing the connection with the server it forks.  Then
  child sends the keyboard input to the server until EOF is received and
  the parent receives answers from the server.

       /*
        *      Sample client fragment,
        *      variables declarations and error handling are omitted
        */
               s=connect(...);

               if( fork() ){   /*      The child, it copies its stdin to
                                               the socket              */
                       while( gets(buffer) >0)
                               write(s,buf,strlen(buffer));

                       close(s);
                       exit(0);
                       }

               else {          /* The parent, it receives answers  */
                       while( (l=read(s,buffer,sizeof(buffer)){
                               do_something(l,buffer);

                       /* Connection break from the server is assumed  */
                       /* ATTENTION: deadlock here                     */
                       wait(0); /* Wait for the child to exit          */
                       exit(0);
                       }

  What do we expect? The child detects an EOF from its stdin, it closes
  the socket (assuming connection break) and exits.  The server in its
  turn detects EOF, closes connection and exits.  The parent detects
  EOF, makes the wait() system call and exits.  What do we see instead?
  The socket instance in the parent process is still opened for writing
  and reading, though the parent never writes.  The server never detects
  EOF and waits for more data from the client forever.  The parent never
  sees the connection is closed and hangs forever and the server hangs
  too.  Unexpected deadlock!  ( any deadlock is unexpected though :-)

  You should change the client fragment as follows:

                       if( fork() ) {  /* The child                    */
                               while( gets(buffer) }
                                       write(s,buffer,strlen(buffer));

                                       shutdown(s,1); /* Break the connection
               for writing, The server will detect EOF now. Note: reading from
               the socket is still allowed. The server may send some more data
               after receiving EOF, why not? */
                               exit(0);
                               }

  I hope this rough example explains the troubles you can have with
  client/server syncronization.  Generally you should always remember
  all the instances of the particular socket in all the processes that
  share the socket and close them all at once if you whish to use
  close() or use shutdown() in one process to break the connection.

  2.7.  Please explain the TIME_WAIT state.

  Remember that TCP guarantees all data transmitted will be delivered,
  if at all possible.  When you close a socket, the server goes into a
  TIME_WAIT state, just to be really really sure that all the data has
  gone through.  When a socket is closed, both sides agree by sending
  messages to each other that they will send no more data.  This, it
  seemed to me was good enough, and after the handshaking is done, the
  socket should be closed.  The problem is two-fold.  First, there is no
  way to be sure that the last ack was communicated successfully.
  Second, there may be "wandering duplicates" left on the net that must
  be dealt with if they are delivered.

  Andrew Gierth (andrew@erlenstar.demon.co.uk) helped to explain the
  closing sequence in the following usenet posting:

  Assume that a connection is in ESTABLISHED state, and the client is
  about to do an orderly release. The client's sequence no. is Sc, and
  the server's is Ss. The pipe is empty in both directions.

          Client                                                   Server
          ======                                                   ======
          ESTABLISHED                                              ESTABLISHED
          (client closes)
          ESTABLISHED                                              ESTABLISHED
                        ------->>
          FIN_WAIT_1
                       <<-------- 
          FIN_WAIT_2                                               CLOSE_WAIT
                       <<--------   (server closes)
                                                                   LAST_ACK
                       , ------->>
          TIME_WAIT                                                CLOSED
          (2*msl elapses...)
          CLOSED

  Note: the +1 on the sequence numbers is because the FIN counts as one
  byte of data. (The above diagram is equivalent to fig. 13 from RFC
  793).

  Now consider what happens if the last of those packets is dropped in
  the network. The client has done with the connection; it has no more
  data or control info to send, and never will have. But the server does
  not know whether the client received all the data correctly; that's
  what the last ACK segment is for. Now the server may or may not care
  whether the client got the data, but that is not an issue for TCP; TCP
  is a reliable rotocol, and must distinguish between an orderly
  connection close where all data is transferred, and a connection abort
  where data may or may not have been lost.

  So, if that last packet is dropped, the server will retransmit it (it
  is, after all, an unacknowledged segment) and will expect to see a
  suitable ACK segment in reply.  If the client went straight to CLOSED,
  the only possible response to that retransmit would be a RST, which
  would indicate to the server that data had been lost, when in fact it
  had not been.

  (Bear in mind that the server's FIN segment may, additionally, contain
  data.)

  DISCLAIMER: This is my interpretation of the RFCs (I have read all the
  TCP-related ones I could find), but I have not attempted to examine
  implementation source code or trace actual connections in order to
  verify it. I am satisfied that the logic is correct, though.

  More commentarty from Vic:

  The second issue was addressed by Richard Stevens (rstevens@noao.edu,
  author of "Unix Network Programming", see ``1.5 Where can I get source
  code for the book [book  title]?'').  I have put together quotes from
  some of his postings and email which explain this.  I have brought
  together paragraphs from different postings, and have made as few
  changes as possible.

  From Richard Stevens (rstevens@noao.edu):

  If the duration of the TIME_WAIT state were just to handle TCP's full-
  duplex close, then the time would be much smaller, and it would be
  some function of the current RTO (retransmission timeout), not the MSL
  (the packet lifetime).

  A couple of points about the TIME_WAIT state.

  o  The end that sends the first FIN goes into the TIME_WAIT state,
     because that is the end that sends the final ACK.  If the other
     end's FIN is lost, or if the final ACK is lost, having the end that
     sends the first FIN maintain state about the connection guarantees
     that it has enough information to retransmit the final ACK.

  o  Realize that TCP sequence numbers wrap around after 2**32 bytes
     have been transferred.  Assume a connection between A.1500 (host A,
     port 1500) and B.2000.  During the connection one segment is lost
     and retransmitted.  But the segment is not really lost, it is held
     by some intermediate router and then re-injected into the network.
     (This is called a "wandering duplicate".)  But in the time between
     the packet being lost & retransmitted, and then reappearing, the
     connection is closed (without any problems) and then another
     connection is established between the same host, same port (that
     is, A.1500 and B.2000; this is called another "incarnation" of the
     connection).  But the sequence numbers chosen for the new
     incarnation just happen to overlap with the sequence number of the
     wandering duplicate that is about to reappear.  (This is indeed
     possible, given the way sequence numbers are chosen for TCP
     connections.)  Bingo, you are about to deliver the data from the
     wandering duplicate (the previous incarnation of the connection) to
     the new incarnation of the connection.  To avoid this, you do not
     allow the same incarnation of the connection to be reestablished
     until the TIME_WAIT state terminates.

     Even the TIME_WAIT state doesn't complete solve the second problem,
     given what is called TIME_WAIT assassination.  RFC 1337 has more
     details.

  o  The reason that the duration of the TIME_WAIT state is 2*MSL is
     that the maximum amount of time a packet can wander around a
     network is assumed to be MSL seconds.  The factor of 2 is for the
     round-trip.  The recommended value for MSL is 120 seconds, but
     Berkeley-derived implementations normally use 30 seconds instead.
     This means a TIME_WAIT delay between 1 and 4 minutes.  Solaris 2.x
     does indeed use the recommended MSL of 120 seconds.

  A wandering duplicate is a packet that appeared to be lost and was
  retransmitted.  But it wasn't really lost ... some router had
  problems, held on to the packet for a while (order of seconds, could
  be a minute if the TTL is large enough) and then re-injects the packet
  back into the network.  But by the time it reappears, the application
  that sent it originally has already retransmitted the data contained
  in that packet.

  Because of these potential problems with TIME_WAIT assassinations, one
  should not avoid the TIME_WAIT state by setting the SO_LINGER option
  to send an RST instead of the normal TCP connection termination
  (FIN/ACK/FIN/ACK).  The TIME_WAIT state is there for a reason; it's
  your friend and it's there to help you :-)

  I have a long discussion of just this topic in my just-released
  "TCP/IP Illustrated, Volume 3".  The TIME_WAIT state is indeed, one of
  the most misunderstood features of TCP.

  I'm currently rewriting "Unix Network Programming" (see ``1.5 Where
  can I get source code for the book [book  title]?''). and will include
  lots more on this topic, as it is often confusing and misunderstood.

  An additional note from Andrew:

  Closing a socket: if SO_LINGER has not been called on a socket, then
  close() is not supposed to discard data. This is true on SVR4.2 (and,
  apparently, on all non-SVR4 systems) but apparently not on SVR4; the
  use of either shutdown() or SO_LINGER seems to be required to
  guarantee delivery of all data.

  2.8.  Why does it take so long to detect that the peer died?

  From Andrew Gierth (andrew@erlenstar.demon.co.uk):

  Because by default, no packets are sent on the TCP connection unless
  there is data to send or acknowledge.

  So, if you are simply waiting for data from the peer, there is no way
  to tell if the peer has silently gone away, or just isn't ready to
  send any more data yet. This can be a problem (especially if the peer
  is a PC, and the user just hits the Big Switch...).

  One solution is to use the SO_KEEPALIVE option. This option enables
  periodic probing of the connection to ensure that the peer is still
  present.  BE WARNED: the default timeout for this option is AT LEAST 2
  HOURS.  This timeout can often be altered (in a system-dependent
  fashion) but not normally on a per-connection basis (AFAIK).

  RFC1122 specifies that this timeout (if it exists) must be
  configurable.  On the majority of Unix variants, this configuration
  may only be done globally, affecting all TCP connections which have
  keepalive enabled. The method of changing the value, moreover, is
  often difficult and/or poorly documented, and in any case is different
  for just about every version in existence.

  If you must change the value, look for something resembling
  tcp_keepidle in your kernel configuration or network options
  configuration.

  If you're sending to the peer, though, you have some better
  guarantees; since sending data implies receiving ACKs from the peer,
  then you will know after the retransmit timeout whether the peer is
  still alive. But the retransmit timeout is designed to allow for
  various contingencies, with the intention that TCP connections are not
  dropped simply as a result of minor network upsets. So you should
  still expect a delay of several minutes before getting notification of
  the failure.

  The approach taken by most application protocols currently in use on
  the Internet (e.g. FTP, SMTP etc.) is to implement read timeouts on
  the server end; the server simply gives up on the client if no
  requests are received in a given time period (often of the order of 15
  minutes). Protocols where the connection is maintained even if idle
  for long periods have two choices:

  1. use SO_KEEPALIVE

  2. use a higher-level keepalive mechanism (such as sending a null
     request to the server every so often).

  2.9.  What are the pros/cons of select(), non-blocking I/O and SIGIO?

  Using non-blocking I/O means that you have to poll sockets to see if
  there is data to be read from them.  Polling should usually be avoided
  since it uses more CPU time than other techniques.

  Using SIGIO allows your application to do what it does and have the
  operating system tell it (with a signal) that there is data waiting
  for it on a socket.  The only drawback to this soltion is that it can
  be confusing, and if you are dealing with multiple sockets you will
  have to do a select() anyway to find out which one(s) is ready to be
  read.

  Using select() is great if your application has to accept data from
  more than one socket at a time since it will block until any one of a
  number of sockets is ready with data.  One other advantage to select()
  is that you can set a time-out value after which control will be
  returned to you whether any of the sockets have data for you or not.

  2.10.  Why do I get EPROTO from read()?

  From Steve Rago (sar@plc.com):

  EPROTO means that the protocol encountered an unrecoverable error for
  that endpoint.  EPROTO is one of those catch-all error codes used by
  STREAMS-based drivers when a better code isn't available.

  And an addition note from Andrew (andrew@erlenstar.demon.co.uk):

  Not quite to do with EPROTO from read(), but I found out once that on
  some STREAMS-based implementations, EPROTO could be returned by
  accept() if the incoming connection was reset before the accept
  completes.

  On some other implementations, accept seemed to be capable of blocking
  if this occured. This is important, since if select() said the
  listening socket was readable, then you would normally expect not to

Section 1 of 4 - Prev - Next
All sections - 1 - 2 - 3 - 4

Back to category unix-faq - Use Smart Search
Home - Smart Search - About the project - Feedback

© allanswers.org | Terms of use

LiveInternet