UNPv1第二十章:高级UDP套接口编程

来源:互联网 发布:一个程序员的奋斗史39 编辑:程序博客网 时间:2024/05/16 09:54

1.接收标志、目的IP地址和接口索引

作为recvmsg的一个例子,我们将要写一个名为recvfrom_flags的函数,它与recvfrom类似,但他还返回:

  1. 返回的msg_flags值
  2. 收到的数据报的目的地址(通过设置IP_RECVDSTADDR套接口选项)
  3. 接收数据报接口的索引(通过设置IP_RECIF套接口选项)

为了返回最后两项,我们定义如下结构:

struct in_pktinfo{  struct in_addr ipi_addr;   /* destination IPv4 address */  int  ipi_ifindex;  /* received interface index */};

2.数据报截断

前一节的例子中表明,当一个UDP数据报长度大于应用进程缓冲区时,recvmsg在msghdr结构中的msg_flags成员上设置MSG_TRUNC标志。但并非所有实现都以这种方式处理超过预期长度的UDP数据报。这里有三种可能情形:
1. 丢掉超出的字节并给应用进程返回MSG_TRUNC标志。这要求应用进程调用recvmsg来接收这个标志。
2. 丢到超出的字节但不通知应用进程。
3. 保留超出的字节并在随后这个套接口上的读操作中返回这些数据。

3.何时用UDP代替TCP

 使用广播或者多播时候,因为UDP支持广播或多播
 对于简单的请求-应答应用程序应使用UDP,但程序内部必须有检查错误的功能。这至少涉及确认、超时和重传
 对于海量数据传输(例如文件传输)不应该使用UDP

4.给UDP应用增加可靠性

如果我们想要在请求-应答式应用程序中使用UDP,那么我们必须对我们的客户增加两个特性:

  1. 超时和重传以处理丢失的数据报
  2. 序列号,这样客户可以验证一个应答是对应相应的请求的

这两个特性是多数使用简单的请求-应答范例的现有UDP应用程序的一部分:例如DNS解析器,SNMP代理,TFTP和RPC。
加入序列号比较简单。客户给每个请求附加一个序列号,并且服务器必须在应答中给客户返回这个号,这样可以让客户验证给定的应答是对应所发请求的应答。
老式的处理超时和重传的方法是发送一个请求后等待N秒。如果没有收到应答,则重传并再等待另外N秒。这种情况发生一定次数后放弃。这是一种线性重传定时器。这种方法的问题是数据报在一个互联网上往返的时间会从LAN上的远远不到一秒变到WAN上的许多秒。影响往返时间(RTT)的因素是距离、网速、拥塞。我们必须采用一个将实际测得的RTT以及RTT随时间的变化考虑在内的超时和重传算法。

“重传二义性问题”,当重传定时器超时时,三种可能的情形:
1). 请求丢失了
2). 应答丢失了
3). RTO太小

5.并发UDP服务器

当使用TCP时,能够简化服务器并发性的根源在于每个客户连接都是唯一的,也就是说TCP套接口对于每个连接都是唯一的。然而对于UDP,我们必须处理两个不同类型的服务器。

1). 第一种是简单的UDP服务器,它读入一个客户请求,发送应答,接着与这个客户就无关了。在这种情形里,读客户请求的服务器可以fork一个子进程去处理请求。“请求”(也就是数据报的内容和保存在客户协议地址中的套接口地址结构)通过从fork得来的内存映像传递给子进程。子进程接着直接给客户发送它的应答。

2). 第二种是与客户交换多个数据报的UDP服务器。问题是客户只知道服务器的端口是服务器众所周知的端口。客户发送请求的第一个数据报到这个端口,但是服务器又怎么能区分这是那个客户的后继数据报还是新的请求呢?这种问题的典型解决方法是让服务器给每个客户创建一个新的套接字,bind一个临时端口,然后使用该套接字并发送对该客户的所有应答。

6.IPv6分组信息

IPv6允许应用程序对外出的数据报指定最多四条信息:
 源IPv6地址
 外出接口索引
 外出跳限
 下一跳地址
这些信息是作为辅助数据使用sendmsg发送的。对于收到的分组可以返回三条类似的信息,他们是作为辅助数据由recvmsg返回的:
 目的IPv6地址
 到达接口索引
 到达跳限
这里写图片描述
in6_pktinfo结构含有发送数据报的源IPv6地址和外出接口索引,或者含有收到的数据报的目的IPv6地址和到达接口索引:

struct in6_pktinfo{   struct in6_addr  ipi6_addr;  /* src / dst IPv6 address */int  ipi6_ifindex;  /* send / recv interface index */};

发送该信息不要什么特别的要求:只是给sendmsg指定作为辅助数据的控制信息。但是,只有应用程序打开了IPv6_PKTINFO套接口选项,这个信息才会有recvmsg作为辅助数据返回。

0 0
原创粉丝点击