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

📄 24.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 4 页
字号:
  And an addition note from Andrew (andrew@erlenstar.demon.co.uk): <br>

  Not quite to do with EPROTO from read(), but I found out once that on <br>

  some STREAMS-based implementations, EPROTO could be returned by <br>

  accept() if the incoming connection was reset before the accept <br>

  completes. <br>

  On some other implementations, accept seemed to be capable of blocking <br>

  if this occured. This is important, since if select() said the <br>

  listening socket was readable, then you would normally expect not to <br>

  block in the accept() call. The fix is, of course, to set nonblocking <br>

  mode on the listening socket if you are going to use select() on it. <br>

  <br>

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

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

  You can't force it.  Period.  TCP makes up its own mind as to when it <br>

  can send data.  Now, normally when you call write() on a TCP socket, <br>

  TCP will indeed send a segment, but there's no guarantee and no way to <br>

  force this.  There are lots of reasons why TCP will not send a <br>

  segment: a closed window and the Nagle algorithm are two things to <br>



  come immediately to mind. <br>

  (Snipped suggestion from Andrew Gierth to use TCP_NODELAY) <br>

  Setting this only disables one of the many tests, the Nagle algorithm. <br>

  But if the original poster's problem is this, then setting this socket <br>

  option will help. <br>

  A quick glance at tcp_output() shows around 11 tests TCP has to make <br>

  as to whether to send a segment or not. <br>

  Now from Dr. Charles E. Campbell Jr.  (cec@gryphon.gsfc.nasa.gov): <br>

  As you've surmised, I've never had any problem with disabling Nagle's <br>

  algorithm.  Its basically a buffering method; there's a fixed overhead <br>

  for all packets, no matter how small.  Hence, Nagle's algorithm <br>

  collects small packets together (no more than .2sec delay) and thereby <br>

  reduces the amount of overhead bytes being transferred.  This approach <br>

  works well for rcp, for example: the .2 second delay isn't humanly <br>

  noticeable, and multiple users have their small packets more <br>

  efficiently transferred.  Helps in university settings where most <br>

  folks using the network are using standard tools such as rcp and ftp, <br>

  and programs such as telnet may use it, too. <br>

  However, Nagle's algorithm is pure havoc for real-time control and not <br>

  much better for keystroke interactive applications (control-C, <br>

  anyone?).  It has seemed to me that the types of new programs using <br>

  sockets that people write usually do have problems with small packet <br>



  delays.  One way to bypass Nagle's algorithm selectively is to use <br>

  "out-of-band" messaging, but that is limited in its content and has <br>

  other effects (such as a loss of sequentiality) (by the way, out-of- <br>

  band is often used for that ctrl-C, too). <br>

  More from Vic: <br>

  So to sum it all up, if you are having trouble and need to flush the <br>

  socket, setting the TCP_NODELAY option will usually solve the problem. <br>

  If it doesn't, you will have to use out-of-band messaging, but <br>

  according to Andrew, "out-of-band data has its own problems, and I <br>

  don't think it works well as a solution to buffering delays (haven't <br>

  tried it though).  It is not 'expedited data' in the sense that exists <br>

  in some other protocols; it is transmitted in-stream, but with a <br>

  pointer to indicate where it is." <br>

  I asked Andrew something to the effect of "What promises does TCP make <br>

  about when it will get around to writing data to the network?"  I <br>

  thought his reply should be put under this question: <br>

  Not many promises, but some. <br>

  I'll try and quote chapter and verse on this: <br>

  References: <br>

       RFC 1122, "Requirements for Internet Hosts" (also STD 3) <br>

       RFC  793, "Transmission Control Protocol"   (also STD 7) <br>

  1. The socket interface does not provide access to the TCP PUSH flag. <br>



  2. RFC1122 says (4.2.2.2): <br>

     A TCP MAY implement PUSH flags on SEND calls.  If PUSH flags are <br>

     not implemented, then the sending TCP: (1) must not buffer data <br>

     indefinitely, and (2) MUST set the PSH bit in the last buffered <br>

     segment (i.e., when there is no more queued data to be sent). <br>

  3. RFC793 says (2.8): <br>

     When a receiving TCP sees the PUSH flag, it must not wait for more <br>

     data from the sending TCP before passing the data to the receiving <br>

     process. <br>

     [RFC1122 supports this statement.] <br>

  4. Therefore, data passed to a write() call must be delivered to the <br>

     peer within a finite time, unless prevented by protocol <br>

     considerations. <br>

  5. There are (according to a post from Stevens quoted in the FAQ <br>

     [earlier in this answer - Vic]) about 11 tests made which could <br>

     delay sending the data. But as I see it, there are only 2 that are <br>

     significant, since things like retransmit backoff are a) not under <br>

     the programmers control and b) must either resolve within a finite <br>

     time or drop the connection. <br>

  The first of the interesting cases is "window closed"  (ie. there is <br>

  no buffer space at the receiver; this can delay data indefinitely, but <br>

  only if the receiving process is not actually reading the data that is <br>



  available) <br>

  Vic asks: <br>

  OK, it makes sense that if the client isn't reading, the data isn't <br>

  going to make it across the connection.  I take it this causes the <br>

  sender to block after the recieve queue is filled? <br>

  The sender blocks when the socket send buffer is full, so buffers will <br>

  be full at both ends. <br>

  While the window is closed, the sending TCP sends window probe <br>

  packets. This ensures that when the window finally does open again, <br>

  the sending TCP detects the fact. [RFC1122, ss 4.2.2.17] <br>

  The second interesting case is "Nagle algorithm" (small segments, e.g. <br>

  keystrokes, are delayed to form larger segments if ACKs are expected <br>

  from the peer; this is what is disabled with TCP_NODELAY) <br>

  Vic Asks: <br>

  Does this mean that my tcpclient sample should set TCP_NODELAY to <br>

  ensure that the end-of-line code is indeed put out onto the network <br>

  when sent? <br>

  No. tcpclient.c is doing the right thing as it stands; trying to write <br>

  as much data as possible in as few calls to write() as is feasible. <br>

  Since the amount of data is likely to be small relative to the socket <br>

  send buffer, then it is likely (since the connection is idle at that <br>

  point) that the entire request will require only one call to write(), <br>



  and that the TCP layer will immediately dispatch the request as a <br>

  single segment (with the PSH flag, see point 2.2 above). <br>

  The Nagle algorithm only has an effect when a second write() call is <br>

  made while data is still unacknowledged. In the normal case, this data <br>

  will be left buffered until either: a) there is no unacknowledged <br>

  data; or b) enough data is available to dispatch a full-sized segment. <br>

  The delay cannot be indefinite, since condition (a) must become true <br>

  within the retransmit timeout or the connection dies. <br>

  Since this delay has negative consequences for certain applications, <br>

  generally those where a stream of small requests are being sent <br>

  without response, e.g. mouse movements, the standards specify that an <br>

  option must exist to disable it. [RFC1122, ss 4.2.3.4] <br>

  Additional note: RFC1122 also says: <br>

     [DISCUSSION]: <br>

        When the PUSH flag is not implemented on SEND calls, i.e., when <br>

        the application/TCP interface uses a pure streaming model, <br>

        responsibility for aggregating any tiny data fragments to form <br>

        reasonable sized segments is partially borne by the application <br>

        layer. <br>

  So programs should avoid calls to write() with small data lengths <br>

  (small relative to the MSS, that is); it's better to build up a <br>

  request in a buffer and then do one call to sock_write() or <br>



  equivalent. <br>

  The other possible sources of delay in the TCP are not really <br>

  controllable by the program, but they can only delay the data <br>

  temporarily. <br>

  Vic asks: <br>

  By temporarily, you mean that the data will go as soon as it can, and <br>

  I won't get stuck in a position where one side is waiting on a <br>

  response, and the other side hasn't recieved the request?  (Or at <br>

  least I won't get  stuck forever) <br>

  You can only deadlock if you somehow manage to fill up all the buffers <br>

  in both directions... not easy. <br>

  If it is possible to do this, (can't think of a good example though), <br>

  the solution is to use nonblocking mode, especially for writes. Then <br>

  you can buffer excess data in the program as necessary. <br>

  <br>

2.12.  Where can a get a library for programming sockets? <br>

  There is the Simple Sockets Library by Charles E. Campbell, Jr. PhD. <br>

  and Terry McRoberts.  The file is called ssl.tar.gz, and you can <br>

  download it from this faq's home page.  For c++ there is the Socket++ <br>

  library which is on ftp://ftp.virginia.edu/pub/socket++-1.10.tar.gz. <br>

  There is also C++ Wrappers.  The file is called <br>

  ftp://ftp.huji.ac.il/pub/languages/C++/C++_wrappers.tar.gz.  Thanks to <br>



  Bill McKinnon for tracking it down for me!  From <br>

  http://www.cs.wustl.edu/~schmidt you should be able to find the ACE <br>

  toolkit.  PING Software Group has some libraries that include a <br>

  sockets interface among other things.  You can find them at <br>

  http://love.geology.yale.edu/~markl/ping. <br>

  I don't have any experience with any of these libraries, so I can't <br>

  recomend one over the other. <br>

  <br>

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

  The data that causes select to return is the EOF because the other <br>

  side has closed the connection.  This causes read to return zero.  For <br>

  more information see ``2.1 How can I tell when a socket is closed on <br>

  the other end?'' <br>

  <br>

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

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

  The basic difference is that select()'s fd_set is a bit mask and <br>

  therefore has some fixed size.  It would be possible for the kernel to <br>

  not limit this size when the kernel is compiled, allowing the <br>

  application to define FD_SETSIZE to whatever it wants (as the comments <br>

  in the system header imply today) but it takes more work.  4.4BSD's <br>

  kernel and the Solaris library function both have this limit.  But I <br>



  see that BSD/OS 2.1 has now been coded to avoid this limit, so it's <br>

  doable, just a small matter of programming. :-)  Someone should file a <br>

  Solaris bug report on this, and see if it ever gets fixed. <br>

  With poll(), however, the user must allocate an array of pollfd <br>

  structures, and pass the number of entries in this array, so there's <br>

  no fundamental limit.  As Casper notes, fewer systems have poll() than <br>

  select, so the latter is more portable.  Also, with original <br>

  implementations (SVR3) you could not set the descriptor to -1 to tell <br>

  the kernel to ignore an entry in the pollfd structure, which made it <br>

  hard to remove entries from the array; SVR4 gets around this. <br>

  Personally, I always use select() and rarely poll(), because I port my <br>

  code to BSD environments too.  Someone could write an implementation <br>

  of poll() that uses select(), for these environments, but I've never <br>

  seen one. Both select() and poll() are being standardized by POSIX <br>

  1003.1g. <br>

  <br>

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

  Anything other than single bytes of data will probably get mangled <br>

  unless you take care.  For integer values you can use htons() and <br>

  friends, and strings are really just a bunch of single bytes, so those <br>

  should be OK.  Be careful not to send a pointer to a string though, <br>

  since the pointer will be meaningless on another machine.  If you need <br>



  to send a struct, you should write sendthisstruct() and <br>

  readthisstruct() functions for it that do all the work of taking the <br>

⌨️ 快捷键说明

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