⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 24.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 4 页
字号:
  structure apart on one side, and putting it back together on the <br>

  other.  If you need to send floats, you may have a lot of work ahead <br>

  of you.  You should read RFC 1014 which is about portable ways of <br>

  getting data from one machine to another (thanks to Andrew Gabriel for <br>

  pointing this out). <br>

  <br>

2.16.  How do I use TCP_NODELAY? <br>

  First off, be sure you really want to use it in the first place.  It <br>

  will disable the Nagle algorithm (see ``2.11 How can I force a socket <br>

  to send the data in its buffer?''), which will cause network traffic <br>

  to increase, with smaller than needed packets wasting bandwidth. <br>

  Also, from what I have been able to tell, the speed increase is very <br>

  small, so you should probably do it without TCP_NODELAY first, and <br>

  only turn it on if there is a problem. <br>

  Here is a code example, with a warning about using it from Andrew <br>

  Gierth: <br>

         int flag = 1; <br>

         int result = setsockopt(sock,            /* socket affected */ <br>

                                 IPPROTO_TCP,     /* set option at TCP level <br>

 */ <br>

 */ <br>

                                 TCP_NODELAY,     /* name of option */ <br>

                                 (char *) &flag,  /* the cast is historical <br>

                                                         cruft */ <br>

                                 sizeof(int));    /* length of option value <br>

*/ <br>

         if (result < 0) <br>

            ... handle the error ... <br>

  TCP_NODELAY is for a specific purpose; to disable the Nagle buffering <br>

  algorithm. It should only be set for applications that send frequent <br>

  small bursts of information without getting an immediate response, <br>

  where timely delivery of data is required (the canonical example is <br>

  mouse movements). <br>

  <br>

2.17.  What exactly does the Nagle algorithm do? <br>

  It groups together as much data as it can between ACK's from the other <br>

  end of the connection.  I found this really confusing until Andrew <br>

  Gierth (andrew@erlenstar.demon.co.uk) drew the following diagram, and <br>

  explained: <br>

  This diagram is not intended to be complete, just to illustrate the <br>

  point better... <br>

  Case 1: client writes 1 byte per write() call. The program on host B <br>

  is tcpserver.c from the FAQ examples. <br>



        CLIENT                                  SERVER <br>

  APP             TCP                     TCP             APP <br>

                  [connection setup omitted] <br>

   "h" --------->          [1 byte] <br>

                      ------------------> <br>

                                             -----------> "h" <br>

                                     [ack delayed] <br>

   "e" ---------> [Nagle alg.              . <br>

                   now in effect]          . <br>

   "l" ---------> [ditto]                  . <br>

   "l" ---------> [ditto]                  . <br>

   "o" ---------> [ditto]                  . <br>

   "\n"---------> [ditto]                  . <br>

                                           . <br>

                                           . <br>

                         [ack 1 byte] <br>

                      <------------------ <br>

                  [send queued <br>

                  data] <br>

                          [5 bytes] <br>

                      ------------------> <br>

                                            ------------> "ello\n" <br>



                                            <------------ "HELLO\n" <br>

                     [6 bytes, ack 5 bytes] <br>

                      <------------------ <br>

   "HELLO\n" <---- <br>

                [ack delayed] <br>

                   . <br>

                   . <br>

                   .   [ack 6 bytes] <br>

                      ------------------> <br>

  Total segments: 5. (If TCP_NODELAY was set, could have been up to 10.) <br>

  Time for response: 2*RTT, plus ack delay. <br>

  Case 2: client writes all data with one write() call. <br>

             CLIENT                                  SERVER <br>

       APP             TCP                     TCP             APP <br>

                       [connection setup omitted] <br>

        "hello\n" --->          [6 bytes] <br>

                           ------------------> <br>

                                                 ------------> "hello\n" <br>

                                                 <------------ "HELLO\n" <br>

                          [6 bytes, ack 6 bytes] <br>

                           <------------------ <br>

        "HELLO\n" <---- <br>



                   [ack delayed] <br>

                        . <br>

                        . <br>

                        .   [ack 6 bytes] <br>

                           ------------------> <br>

  Total segments: 3. <br>

  Time for response = RTT (therefore minimum possible). <br>

  Hope this makes things a bit clearer... <br>

  Note that in case 2, you don't want the implementation to gratuitously <br>

  delay sending the data, since that would add straight onto the <br>

  response time. <br>

  <br>

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

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

  read() is equivalent to recv() with a flags parameter of 0.  Other <br>

  values for the flags parameter change the behaviour of recv(). <br>

  Similarly, write() is equivalent to send() with flags == 0. <br>

  It is unlikely that send()/recv() would be dropped; perhaps someone <br>

  with a copy of the POSIX drafts for socket calls can check... <br>

  Portability note: non-unix systems may not allow read()/write() on <br>

  sockets, but recv()/send() are usually ok. This is true on Windows and <br>

  OS/2, for example. <br>



  <br>

2.19.  I see that send()/write() can generate SIGPIPE. Is there any <br>

  advantage to handling the signal, rather than just ignoring it and <br>

  checking for the EPIPE error? Are there any useful parameters passed <br>

  to the signal catching function? <br>

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

  In general, the only parameter passed to a signal handler is the <br>

  signal number that caused it to be invoked.  Some systems have <br>

  optional additional parameters, but they are no use to you in this <br>

  case. <br>

  My advice is to just ignore SIGPIPE as you suggest. That's what I do <br>

  in just about all of my socket code; errno values are easier to handle <br>

  than signals (in fact, the first revision of the FAQ failed to mention <br>

  SIGPIPE in that context; I'd got so used to ignoring it...) <br>

  There is one situation where you should not ignore SIGPIPE; if you are <br>

  going to exec() another program with stdout redirected to a socket. In <br>

  this case it is probably wise to set SIGPIPE to SIG_DFL before doing <br>

  the exec(). <br>

  <br>

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

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

  On systems where sockets are implemented on top of Streams (e.g. all <br>



  SysV-based systems, presumably including Solaris), the socket() <br>

  function will actually be opening certain special files in /dev. You <br>

  will need to create a /dev directory under your fake root and populate <br>

  it with the required device nodes (only). <br>

  Your system documentation may or may not specify exactly which device <br>

  nodes are required; I can't help you there (sorry).  (Editors note: <br>

  Adrian Hall (adrian@waltham.harvard.net) suggested checking the man <br>

  page for ftpd, which should list the files you need to copy and <br>

  devices you need to create in the chroot'd environment.) <br>

  A less-obvious issue with chroot() is if you call syslog(), as many <br>

  daemons do; syslog() opens (depending on the system) either a UDP <br>

  socket, a FIFO or a Unix-domain socket. So if you use it after a <br>

  chroot() call, make sure that you call openlog() *before* the chroot. <br>

  <br>

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

  This isn't really so much an error as an exit condition.  It means <br>

  that the call was interrupted by a signal.  Any call that might block <br>

  should be wrapped in a loop that checkes for EINTR, as is done in the <br>

  example code (See ``6. Sample Source Code''). <br>

  <br>

2.22.  When will my application receive SIGPIPE? <br>

  From Richard Stevens (rstevens@noao.edu): <br>



  Very simple: with TCP you get SIGPIPE if your end of the connection <br>

  has received an RST from the other end.  What this also means is that <br>

  if you were using select instead of write, the select would have <br>

  indicated the socket as being readable, since the RST is there for you <br>

  to read (read will return an error with errno set to ECONNRESET). <br>

  Basically an RST is TCP's response to some packet that it doesn't <br>

  expect and has no other way of dealing with.  A common case is when <br>

  the peer closes the connection (sending you a FIN) but you ignore it <br>

  because you're writing and not reading.  (You should be using select.) <br>

  So you write to a connection that has been closed by the other end and <br>

  the oether end's TCP responds with an RST. <br>

  <br>

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

  Unlike exceptions in C++, socket exceptions do not indicate that an <br>

  error has occured.  Socket exceptions usually refer to the <br>

  notification that out-of-band data has arrived.  Out-of-band data <br>

  (called "urgent data" in TCP) looks to the application like a separate <br>

  stream of data from the main data stream.  This can be useful for <br>

  separating two different kinds of data.  Note that just because it is <br>

  called "urgent data" does not mean that it will be delivered any <br>

  faster, or with higher priorety than data in the in-band data stream. <br>

  Also beware that unlike the main data stream, the out-of-bound data <br>



  may be lost if your application can't keep up with it. <br>

  <br>

2.24.  running on?  How can I find the full hostname (FQDN) of the <br>

  system I'm <br>

  From Richard Stevens (rstevens@noao.edu): <br>

  Some systems set the hostname to the FQDN and others set it to just <br>

  the unqualified host name.  I know the current BIND FAQ recommends the <br>

  FQDN, but most Solaris systems, for example, tend to use only the <br>

  unqualified host name. <br>

  Regardless, the way around this is to first get the host's name <br>

  (perhaps an FQDN, perhaps unaualified).  Most systems support the <br>

  Posix way to do this using uname(), but older BSD systems only provide <br>

  gethostname().  Call gethostbyname() to find your IP address.  Then <br>

  take the IP address and call gethostbyaddr().  The h_name member of <br>

  the hostent{} should then be your FQDN. <br>

-- <br>

※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 211.69.197.132] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="16.htm">上一层</a>][<a href="25.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -