验证来自服务器的数据报
客户端recvfrom服务端,通过recvfrom函数中的地址参数记录和验证,接受到的服务器IP地址,只保留服务器发来的数据报。
在服务器有多个IP地址的情况下,得到recvfrom返回的地址后,客户通过DNS找到服务器主机的名字来验证该主机。
udp异步错误
当客户端sendto之后,开始recvfrom等待服务器的响应,可是服务器进程压根就没启动,那么???
服务器所在的主机会返回ICMP端口不可达报文,这个时候客户端那边的sendto已经成功返回,sendto认为只要发出去就成功返回了。
可是这个 由sendto引发的错误并没有返回给sendto本身,这就是异步错误。
为什么要这么设计呢?
在一个客服端往多个服务器发送数据报的情况下,如果sendto出错,进程必须知道是发往哪个地址的数据报出错了,可是recvfrom能够返回的的信息仅有errno,它没办法返回数据报的目的IP端口。那样的话,内核干脆就不返回错误了。你可能会说?recvfrom不是有地址参数吗,这个是建立在成功收到数据后,收到的数据的来源地址。我们现在说的是出错了!!!
导致的结果
客户永远阻塞在它的recvfrom调用之中,等待一个永不出现的服务器应答。
说到这个导致的结果,好像问题很严重啊。
那么解决的方案是什么呢?udp套接字调用connect函数!!!
对于已连接的套接字(调用connect),内核会检查是否存在立即可知的错误,并把错误返回到调用进程。
但是条件是,该套接字不能再给输出操作指定地址端口;能且只能与一个对端交换数据报;可是他能收到异步错误了。
connect在udp套接字的使用附加值
再次调用connect可以指定新的地址端口
如果进程知道自己要 向同一地址端口发送多个数据报,可以调用connect,这样可以提高效率,内核只是从进程中复制一次目的地址。
不然的话每一次,发送都要重新复制一次。