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

📄 27.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="16.htm">上一层</a>][<a href="28.htm">下一篇</a>]
<hr><p align="left"><small>发信人: fion (fion), 信区: UNP <br>

标  题: unix socket faq (6) <br>

发信站: UNIX编程 (2001年07月07日09:47:51 星期六), 站内信件 <br>

  <br>

5.  Writing UDP/SOCK_DGRAM applications <br>

  <br>

5.1.  When should I use UDP instead of TCP? <br>

  UDP is good for sending messages from one system to another when the <br>

  order isn't important and you don't need all of the messages to get to <br>

  the other machine.  This is why I've only used UDP once to write the <br>

  example code for the faq.  Usually TCP is a better solution.  It saves <br>

  you having to write code to ensure that messages make it to the <br>

  desired destination, or to ensure the message ordering.  Keep in mind <br>

  that every additional line of code you add to your project in another <br>

  line that could contain a potentially expensive bug. <br>

  If you find that TCP is too slow for your needs you may be able to get <br>

  better performance with UDP so long as you are willing to sacrifice <br>

  message order and/or reliability. <br>

  UDP must be used to multicast messages to more than one other machine <br>

  at the same time.  With TCP an application would have to open separate <br>

  connections to each of the destination machines and send the message <br>

  once to each target machine.  This limits your application to only <br>

  communicate with machines that it already knows about. <br>



  <br>

5.2.  What is the difference between "connected" and "unconnected" <br>

  sockets? <br>

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

  If a UDP socket is unconnected, which is the normal state after a <br>

  bind() call, then send() or write() are not allowed, since no <br>

  destination address is available; only sendto() can be used to send <br>

  data. <br>

  Calling connect() on the socket simply records the specified address <br>

  and port number as being the desired communications partner. That <br>

  means that send() or write() are now allowed; they use the destination <br>

  address and port given on the connect call as the destination of the <br>

  packet. <br>

  <br>

5.3.  of the socket?  Does doing a connect() call affect the receive <br>

  behaviour <br>

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

  Yes, in two ways.  First, only datagrams from your "connected peer" <br>

  are returned.  All others arriving at your port are not delivered to <br>

  you. <br>

  But most importantly, a UDP socket must be connected to receive ICMP <br>

  errors.  Pp. 748-749 of "TCP/IP Illustrated, Volume 2" give all the <br>



  gory details on why this is so. <br>

  <br>

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

  If the target machine discards the message because there is no process <br>

  reading on the requested port number, it sends an ICMP message to your <br>

  machine which will cause the next system call on the socket to return <br>

  ECONNREFUSED.  Since delivery of ICMP messages is not guarenteed you <br>

  may not recieve this notification on the first transaction. <br>

  Remember that your socket must be "connected" in order to receive the <br>

  ICMP errors.  I've been told, and Alan Cox has verified that Linux <br>

  will return them on "unconnected" sockets.  This may cause porting <br>

  problems if your application isn't ready for it, so Alan tells me <br>

  they've added a SO_BSDCOMPAT flag which can be set for Linux kernels <br>

  after 2.0.0. <br>

  <br>

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

  You have to design your protocol to expect a confirmation back from <br>

  the destination when a message is received.  Of course is the <br>

  confirmation is sent by UDP, then it too is unreliable and may not <br>

  make it back to the sender.  If the sender does not get confirmation <br>

  back by a certain time, it will have to re-transmit the message, maybe <br>

  more than once.  Now the receiver has a problem because it may have <br>



  already received the message, so some way of dropping duplicates is <br>

  required.  Most protocols use a message numbering scheme so that the <br>

  receiver can tell that it has already processed this message and <br>

  return another confirmation.  Confirmations will also have to <br>

  reference the message number so that the sender can tell which message <br>

  is being confirmed.  Confused?  That's why I stick with TCP. <br>

  <br>

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

  You can't.  What you can do is make sure that messages are processed <br>

  in order by using a numbering system as mentioned in ``5.5 How can I <br>

  be sure that a UDP message is received?''.  If you need your messages <br>

  to be received and be received in order you should really consider <br>

  switching to TCP.  It is unlikely that you will be able to do a better <br>

  job implementing this sort of protocol than the TCP people already <br>

  have, without a significant investment of time. <br>

  <br>

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

  The simplest thing to do is simply pick a fairly small delay such as <br>

  one second and stick with it.  The problem is that this can congest <br>

  your network with useless traffic if there is a problem on the lan or <br>

  on the other machine, and this added traffic may only serve to make <br>

  the problem worse. <br>



  A better technique, described with source code in "UNIX Network <br>

  Programming" by Richard Stevens (see ``1.5 Where can I get source code <br>

  for the book [book title]?''), is to use an adaptive timeout with an <br>

  exponential backoff.  This technique keeps statistical information on <br>

  the time it is taking messages to reach a host and adjusts timeout <br>

  values accordingly.  It also doubles the timeout each time it is <br>

  reached as to not flood the network with useless datagrams.  Richard <br>

  has been kind enough to post the source code for the book on the web. <br>

  Check out his home page at http://www.noao.edu/~rstevens. <br>

  <br>

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

  This has to do with the maximum size of a datagram on the two machines <br>

  involved.  This depends on the sytems involved, and the MTU (Maximum <br>

  Transmission Unit).  According to "UNIX Network Programming", all <br>

  TCP/IP implementations must support a minimum IP datagram size of 576 <br>

  bytes, regardless of the MTU.  Assuming a 20 byte IP header and 8 byte <br>

  UDP header, this leaves 548 bytes as a safe maximum size for UDP <br>

  messages.  The maximum size is 65516 bytes.  Some platforms support IP <br>

  fragmentation which will allow datagrams to be broken up (because of <br>

  MTU values) and then re-assembled on the other end, but not all <br>

  implementations support this. <br>

  This information is taken from my reading of "UNIX Netowrk <br>



  Programming" (see ``1.5 Where can I get source code for the book [book <br>

  title]?''). <br>

  Andrew has pointed out the following regarding large UDP messages: <br>

  Another issue is fragmentation. If a datagram is sent which is too <br>

  large for the network interface it is sent through, then the sending <br>

  host will fragment it into smaller packets which are reassembled by <br>

  the receiving host. Also, if there are intervening routers, then they <br>

  may also need to fragment the packet(s), which greatly increases the <br>

  chances of losing one or more fragments (which causes the entire <br>

  datagram to be dropped).  Thus, large UDP datagrams should be avoided <br>

  for applications that are likely to operate over routed nets or the <br>

  Internet proper. <br>

  <br>

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

  From Paul W. Nelson (nelson@thursby.com): <br>

  In the traditional BSD socket implementation, sockets that are atomic <br>

  such as UDP keep received data in lists of mbufs.  An mbuf is a fixed <br>

  size buffer that is shared by various protocol stacks.  When you set <br>

  your receive buffer size, the protocol stack keeps track of how many <br>

  bytes of mbuf space are on the receive buffer, not the number of <br>

  actual bytes.  This approach is used because the resource you are <br>

  controlling is really how many mbufs are used, not how many bytes are <br>



  being held in the socket buffer.  (A socket buffer isn't really a <br>

  buffer in the traditional sense, but a list of mbufs). <br>

  For example:  Lets assume your UNIX has a small mbuf size of 256 <br>

  bytes.  If your receive socket buffer is set to 4096, you can fit 16 <br>

  mbufs on the socket buffer.  If you receive 16 UDP packets that are 10 <br>

  bytes each, your socket buffer is full, and you have 160 bytes of <br>

  data.  If you receive 16 UDP packets that are 200 bytes each, your <br>

  socket buffer is also full, but contains 3200 bytes of data.  FIONREAD <br>

  returns the total number of bytes, not the number of messages or bytes <br>

  of mbufs.  Because of this, it is not a good indicator of how full <br>

  your receive buffer is. <br>

  Additionaly, if you receive UDP messages that are 260 bytes, you use <br>

  up two mbufs, and can only recieve 8 packets before your socket buffer <br>

  is full. In this case, only 2080 bytes of the 4096 are held in the <br>

  socket buffer. <br>

  This example is greatly simplified, and the real socket buffer <br>

  algorithm also takes into account some other parameters.  Note that <br>

  some older socket implementations use a 128 byte mbuf. <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="28.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 + -