下层网络设备接收的包必须由经正确的INET和BSD socket才能被处理 。因此,UDP和TCP维护了一些hash表用来在输入IP消息内查找地址并将它们导向正确的 socket/sock 对 。TCP是一个面向连接的协议,因而涉及处理TCP包的信息比用于处理UDP包的信息多 。
UDP维护着一张已分配UDP端口表,udp_hash 表 。由指向 sock 数据结构的指针组成,通过一个基于端口号的hash函数来索引 。UDPhash表比允许的端口号的数目小得多(udp_hash 为128 或者说是 UDP_HTABLE_SIZE )表中的一些项指向一个 sock 结构链,该链用每个 sock 结构中的 next 指针来将每个 sock 连接起来 。
TCP是十分复杂的,它包括几个hash表 。但实际上TCP在绑定操作时没有将 sock 结构与其hash表绑定,它仅仅检查被请求的端口号当前没被使用 。sock 结构是在 listen 操作时被加入TCP的hash表的 。
复习提要: What about the route entered?
10.4.3在INET BSD Socket上建立连接
建立一个socket,如果没有用它来监听连入请求,那么就能用它来发连出请求 。对于面向无连接的协议如UDP来说,这一socket操作并不做许多事,但对于面向连接的协议如TCP来说,这一操作包括了在两个应用间建立一个虚连接 。
一个连出连接操作只能由一个在正确状态下的INET BSD socket来完成;换句话说,socket不能是已建立连接的,并且有被用来监听连入连接 。这意味着BSD socket 结构必须是 SS_UNCONNECTED 状态 。UDP协议没有在两个应用间建立虚连接,任何发出的消 息都是数据报,这些消息可能到达也可能不到达目的地 。但它不支持BSD socket的 connect 操作 。建立在UDP的INET BSD socket上的连接操作简单地设置远程应用的地址:IP地址和IP端口号 。另外,它还设置路由表入口的cache以便这一BSD socket在发用UDP包时不用再次查询路由数据库(除非这一路由已经无效) 。INET sock 结构中的 ip_route_cache 指针指向路由缓存信息 。如果没有给出地址信息,缓存的路由和IP地址信息将自动地被用来发送消息 。UDP将 sock 的状态改为 TCP_ESTABLISHED。
对于基于TCP BSD socket的连接操作,TCP必须建立一个包括连接信息的TCP消息,并将它送到目的IP 。TCP消息包含与连接有关的信息,一个唯一标识的消息开始顺序号,通过初始化主机来管理的消息大小的最大值,及发送与接收窗口大小等等 。在TCP内,所有的消息都是编号的,初始的顺序号被用来作为第一消息号 。Linux选用一个合理的随机值来避免恶意协议冲突 。每一从TCP连接的一端成功地传到另一端的消息要确认其已经正确到达 。未确认的消息将被重传 。发送与接收窗口的大小是第一个确认到达之前消息的个数 。消息尺寸的最大值与网络设备有关,它们在初始化请求的最后时刻确定下来 。如果接收端的网络设备的消息尺寸最大值更小,则连接将以小的一端为准 。应用程序发出连接请求后必须等待目标应用程序的接受或拒绝连接的响应 。TCP sock 期望着一个输入消息,它被加入 tcp_listening_hash 以便输入TCP消息能被指向这一 sock 结构 。TCP同时也开始计时,当目标应用没有响应请求,则连出连接请求超时 。
10.4.4监听 INET BSD Socket
socket与地址绑定后,能监听指定地址的连入连接请求 。一个网络应用程序能监听socket而不用先将地址 与之绑定;在这个例子中,INET socket层找到一个未用的端口号(对这一协议)并自动将它与socket绑定 。监听socket函数将socket状态设成 TCP_LISTEN,并做其它连入连接所需要的工作 。
对于UDP sockets,改变socket的状态就足够了,而TCP现在加了socket的 sock 数据结构到两个hash表中并激活,tcp_bound_hash 表和 tcp_listening_hash 表 。这两个表都通过一个基于IP端口号的hash函数来索引 。
推荐阅读
- Linux 核心--10.文件系统
- 诺基亚将在更多产品上采用Linux操作系统
- 蛤蟆皮的功效与作用 蛤蟆皮的功效
- Linux 核心--7.PCI设备
- Linux 核心--8.中断与中断处理
- 椰子汤的功效与作用 椰子汤有什么功效
- Linux操作系统如何限制SSH密码尝试次数
- 微软公司对Linux操作系统使出的各种杀招
- Linux 核心--4.内存管理
- 以Linux做路由器的问题