📄 27.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 + -