UDP可以发送长度为0的数据包,包括20字节的IPv4的头部(或者是40字节长的IPv6头部),8字节的UDP头部和没有数据的IP数据报。
这也就意味着recvform返回0值也是可行,并不像TCP的read那样,收到0表示对端关闭连接,因为UDP本身就是非面向连接,也就无断开连接这个概念!
来自客户的IP数据报 TCP服务器 UDP服务器
源IP地址 accept recvfrom
源端口号 accept recvfrom
目的IP地址 getsockname recvmsg
目的端口号 getsockname getsockname
对于UDP的服务器,只有将socket设置了RECVDSTADDR的套接口选项之后,才可以通过调用recvmsg函数来获取IP数据报的目的IP地址
(*) 异步错误: 是指由于目标不可达的ICMP返回错误,只有建立了连接时候,此错误才会被返回到应用进程。
由于sendto函数返回成功只是仅仅表示在输出接口队列上为IP数据报留出空间而已。就算目的IP的服务器不可达(关机或者进程并不是该端口号等),也会返回成功。
对于这个问题,实际上我们可以对UDP调用connect函数,但这个与TCP的不同,不会产生三次握手,内核只是记录对方的IP地址和端口号。
已连接的UDP套接口,与未连接的产生了三个变化:
1、我们再也不能给输出操作制定IP地址和端口号,意味着不能使用sendto,只能使用write和send。写到已连接UDP套接口上的数据自动发送到
由connect指定的协议地址。
2、不用recvform,而是用read或recv。在已连接套接口上内核为输入操作返回的数据报都是那些来自connect指定的协议地址的。不是从connect
协议地址而来的数据报,已连接UDP是不接收的,这也就限定了已连接UDP只能与一个对方交换数据报。
3、异步错误由已连接UDP返回给进程。
(*) 给一个UDP套接口多次调用connect,有两种目的:
1、断开套接口
2、制定新的IP地址和端口号
(*)对UDP套接口connect的另一个副作用:
内核选择本地的IP地址(如果本udp套接口没有调用bind函数指定,如果已经bind过,那么这里就不分配了)。选定的是主IP地址
调用connect后,操作getsockname函数就可以得到内核为UDP已连接套接口分配的本地IP地址。
posted on 2010-08-20 11:30
Eric-guo 阅读(525)
评论(0) 编辑 收藏 引用