⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000011.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 4 页
字号:
对于基于TCP&nbsp;BSD&nbsp;socket的连接操作,TCP必须建立一个包括连接信息的TCP消&nbsp;<BR>息,并将它送到目的IP。TCP消息包含与连接有关的信息,一个唯一标识的消息&nbsp;<BR>开始顺序号,通过初始化主机来管理的消息大小的最大值,及发送与接收窗口&nbsp;<BR>大小等等。在TCP内,所有的消息都是编号的,初始的顺序号被用来作为第一消&nbsp;<BR>息号。Linux选用一个合理的随机值来避免恶意协议冲突。每一从TCP连接的一端&nbsp;<BR>成功地传到另一端的消息要确认其已经正确到达。未确认的消息将被重传。发送&nbsp;<BR>与接收窗口的大小是第一个确认到达之前消息的个数。消息尺寸的最大值与网络&nbsp;<BR>设备有关,它们在初始化请求的最后时刻确定下来。如果接收端的网络设备的消&nbsp;<BR>息尺寸最大值更小,则连接将以小的一端为准。应用程序发出连接请求后必须等&nbsp;<BR>待目标应用程序的接受或拒绝连接的响应。TCPsock&nbsp;期望着一个输入消息,它被&nbsp;<BR>加入&nbsp;tcp_listening_hash以便输入TCP消息能被指向这一&nbsp;sock结构。TCP同时也&nbsp;<BR>开始计时,当目标应用没有响应请求,则连出连接请求超时。&nbsp;<BR>&nbsp;<BR>10.4.4&nbsp;&nbsp;监听&nbsp;INET&nbsp;BSD&nbsp;Socket&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;socket与地址绑定后,能监听指定地址的连入连接请求。一个网络应用程序&nbsp;<BR>能监听socket而不用先将地址与之绑定;在这个例子中,INET&nbsp;socket层找到一&nbsp;<BR>个未用的端口号(对这一协议)并自动将它与socket绑定。监听socket函数将&nbsp;<BR>socket状态设成&nbsp;TCP_LISTEN,并做其它连入连接所需要的工作。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;对于UDP&nbsp;sockets,改变socket的状态就足够了,而TCP现在加了socket的&nbsp;<BR>sock数据结构到两个hash表中并激活,&nbsp;tcp_bound_hash&nbsp;表和&nbsp;tcp_listening_hash&nbsp;<BR>表。这两个表都通过一个基于IP端口号的hash函数来索引。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;无论何时,一个激活的监听socket接收一个连入的TCP连接请求,TCP都要&nbsp;<BR>建立一个新的sock&nbsp;结构来描述它。最终接收时,这个&nbsp;sock结构将成为TCP连接&nbsp;<BR>的底层。它也复制包含连接请求的&nbsp;sk_buff,并将它放到监听&nbsp;sock&nbsp;结构的&nbsp;<BR>receive_queue&nbsp;中排队。复制的&nbsp;sk_buff包含一个指向新建立的&nbsp;sock&nbsp;结构的指针。&nbsp;<BR>&nbsp;<BR>10.4.5&nbsp;&nbsp;接收连接请求&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;UDP不支持连接的概念,接收INET&nbsp;<BR>socket连接请求只适用于TCP协议,一个监听socket接收操作从原始的监听socket&nbsp;<BR>中复制新的socket结构。接收操作透过支持的协议层,本例是INET,来接收任何连&nbsp;<BR>入连接请求。如果下层协议,如UDP,不支持连接,INET协议层接收操作将失败。&nbsp;<BR>否则接收操作透过真实协议层,本例是TCP。接收操作可以是阻塞或非阻塞。在非&nbsp;<BR>阻塞情况下,如果没有连入连接可接收,则接收操作失败,新建的socket结构被废&nbsp;<BR>弃。在阻塞情况下,网络应用程序执行接收操作将加上一个等待队列并将之挂起,&nbsp;<BR>直到接收到TCP连接请求。当接收一个连接请求后,包含请求的sk_buff&nbsp;被废弃,&nbsp;<BR>并且&nbsp;sock&nbsp;数据结构返回到INETsocket层,在那与一个新的更早建立的socket结构&nbsp;<BR>连接。新socket文件描述符(fd)号返回给网络应用程序,然后,应用程序就能在&nbsp;<BR>socket操作中将这一文件描述符用于新建立的INET&nbsp;BSD&nbsp;socket。&nbsp;<BR>&nbsp;<BR>10.5&nbsp;&nbsp;IP层&nbsp;<BR>&nbsp;<BR>10.5.1&nbsp;&nbsp;Socket&nbsp;缓存&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;每一层协议用另外层提供的服务,这样使用多层网络协议会有一个问题:每&nbsp;<BR>个协议都要在传送数据时都要加上协议头和协议尾,而数据到达时又要将之去掉。&nbsp;<BR>这样,在不同的协议间要有数据缓存,每一层需要知道特定协议的头和尾放在哪个&nbsp;<BR>位置。一个解决办法就是在每一层中都拷贝缓存,但这样做效率就很低。Linux用&nbsp;<BR>socket缓存或者说&nbsp;sk_buffs&nbsp;来在协议层与网络设备驱动之间交换数据。&nbsp;<BR>sk_buffs&nbsp;包括指针和字段长度,这样每个协议层就可以通过标准的函数或“方法”&nbsp;<BR>来操作应用程序数据。&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>sk_buff&nbsp;数据结构;每个&nbsp;sk_buff&nbsp;有一个数据块与之相连。&nbsp;<BR>sk_buff&nbsp;有四个指针,这些指针&nbsp;用来操作和管理socket缓存的数据:&nbsp;<BR>&nbsp;<BR>head&nbsp;指向内存中数据区的开头。这一指针在&nbsp;sk_buff和其相关的数据&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;块分配时就固定了。&nbsp;<BR>data&nbsp;指向当前协议数据的开头。这一指针是随当前拥有&nbsp;sk_buff的是&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;哪个协议层而变化的。&nbsp;<BR>tail&nbsp;指向当前协议数据的结尾。同样,这一指针也是随当前拥有&nbsp;sk_buff&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;的是哪个协议层而变化的。&nbsp;<BR>end&nbsp;&nbsp;指向内存中数据区的结尾。这一指针在&nbsp;sk_buff和其相关的数据块&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;分配时固定。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len&nbsp;和&nbsp;truesize这两个字段分别用来描述当前协议包长度和数据&nbsp;<BR>缓存总体长度。&nbsp;sk_buff处理代码提供标准的操作来向应用程序增加和&nbsp;<BR>移除协议头和协议尾。这就可以安全地操作sk_buff&nbsp;中的&nbsp;data&nbsp;,&nbsp;tail&nbsp;<BR>和&nbsp;len&nbsp;字段。&nbsp;<BR>&nbsp;<BR>push&nbsp;它把&nbsp;data&nbsp;指针指向数据区的开始并增加&nbsp;len。用于在要传输的数&nbsp;<BR>据开始处增加协议头。&nbsp;<BR>&nbsp;<BR>pull&nbsp;它把&nbsp;data&nbsp;指针从数据区的开始处移到数据区的结尾处,并减小&nbsp;<BR>len。用于在已接收的数据开始处移除协议头。&nbsp;<BR>&nbsp;<BR>put&nbsp;它把&nbsp;tail&nbsp;指针指向数据区的结尾处,并增加&nbsp;len。用于在要传输&nbsp;<BR>的数据结尾处增加数据或协议信息。&nbsp;<BR>&nbsp;<BR>trim&nbsp;它把&nbsp;tail&nbsp;指针指向数据区的开始处,并减小&nbsp;len。用于在已接&nbsp;<BR>收的数据尾移除数据或协议信息。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;sk_buff&nbsp;结构还包含了用于一些指针,用于在处理过程中存入&nbsp;sk_buff&nbsp;<BR>的双连接环路列表。通用sk_buff例&nbsp;程可以将&nbsp;sk_buff加入到这些列表&nbsp;<BR>的前面或后面,也可以删除它们。&nbsp;<BR>&nbsp;<BR>10.5.2&nbsp;&nbsp;接收IP包&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;第&nbsp;&nbsp;dd-chapter&nbsp;章描述了Linux的网络设备是如何置入内核并初始化的。&nbsp;<BR>一系列device&nbsp;数据结构在&nbsp;dev_base&nbsp;表中相互连接起来。每个&nbsp;device结构&nbsp;<BR>描述了它的设备并提供回调例程,当需要网络驱动来执行工作时,网络协议&nbsp;<BR>层调用这些例程。这些函数与传输的数据及网络设备地址紧密相关。当一个&nbsp;<BR>网络设备从网上接收包时,它必须将接收的数据转换成sk_buff&nbsp;结构。这些&nbsp;<BR>sk_buff&nbsp;则被网络驱动加入到了&nbsp;backlog&nbsp;队列中。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;如果&nbsp;backlog&nbsp;队列太长,则丢弃接收的sk_buff。准备好要运行时,网&nbsp;<BR>络底层将被设置标志。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;当网络底层按计划开始运行后,处理&nbsp;backlog队列之前,任何等待着被&nbsp;<BR>传输的网络包都由它来处理。&nbsp;sk_buff决定哪些层处理被接收的包。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Linux网络层初始化时,每一协议通过将&nbsp;packet_type&nbsp;结构加入到&nbsp;<BR>ptype_all列表或ptype_base&nbsp;hash表中来&nbsp;注册它自己。packet_type结构包&nbsp;<BR>含了协议类型,一个指向网络设备的指针,一个指向协议的接收数据处理例&nbsp;<BR>程的指针,最后还包括一个指向列表链或hash链中下一个packet_type&nbsp;结构&nbsp;<BR>的指针。ptype_all链用于监听从网络设备上接收的所有包,通常不使用它。&nbsp;<BR>ptype_base&nbsp;hash表是被协议标识符弄乱的,用于决定哪个协议将接收传入的&nbsp;<BR>网络包。网络底层通过两个表中的一个或多个packet_type&nbsp;项来匹配传入&nbsp;<BR>sk_buff的协议类型。协议可以和多于一个的项相匹配,如在监听网上所有的&nbsp;<BR>传输时要复制多个sk_buff&nbsp;。&nbsp;sk_buff&nbsp;将通过被匹配协议处理例程。&nbsp;<BR>&nbsp;<BR>10.5.3&nbsp;&nbsp;发送IP包&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;应用程序交换数据时要传输包,否则由网络协议在建立连接或支持一个&nbsp;<BR>已建立的连接时来生成。无论数据是由哪种方法生成的,都要建立一个&nbsp;sk_buff&nbsp;<BR>来包含数据,当通过协议层时,这些协议层会加上各种头。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;sk_buff需要通过网络设备传输。首先协议,如IP,需要确定是哪个网&nbsp;<BR>络设备在用。这有赖于包的最佳路由。对于通过modem连入一个简单网络,&nbsp;<BR>如通过PPP协议,的计算机来说,路由的选择是很简单的。包应该通过本地&nbsp;<BR>环路设备发送给本地主机,或发送给PPPmodem连接的网关。对于连在以在网&nbsp;<BR>上的计算机来说,连接在网络上的计算机越多,路由越复杂。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;对于每一个被传输的IP包,IP用路由表来为目的IP地址解析路由。从路&nbsp;<BR>由表中成功地找到目的IP时将返回一个描述了要使用的路由的rtable&nbsp;结构。&nbsp;<BR>这包括要用到的源IP地址,网络&nbsp;device结构的地址,有时还有预建立的硬件&nbsp;<BR>头。这些硬件头是网络设备特定的,包含了源和目的的物理地址和其它的特&nbsp;<BR>定媒体信息。如果网络设备是一个以太网设备,并且源和目的地址应是物理&nbsp;<BR>的以太网地址。硬件头在路由的时候会缓存起来,因为必须将它加到每一个&nbsp;<BR>要传输的IP包中。硬件头包含的物理地址要用ARP协议来解析。传出的包在地&nbsp;<BR>址被解析后才会发出。解析了地址后,硬件头被缓存起来以便以后的IP包在&nbsp;<BR>使用这一接口时不需要再使用ARP。&nbsp;<BR>&nbsp;<BR>10.5.4&nbsp;&nbsp;数据分块&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;每个网络设备都有一个包大小的最大值,发送或接收数据包不能比这一&nbsp;<BR>值大。IP协议允许将数据分成更小单元以便网络设备能处理。IP协议头有分&nbsp;<BR>块字段,它里面包含了一个标志和分割偏移量。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;当IP包准备要传输时,IP找到网络设备来将IP包发送出去。这个设备是&nbsp;<BR>从IP路由表中找到的。每一device&nbsp;结构中有一项&nbsp;mtu,用来描述最大传输单&nbsp;<BR>元(以字节为单位)。如果设备的&nbsp;mtu比要传输的IP包的包大小要小,则IP&nbsp;<BR>包必须被分割成更小的单元。每一单元用一个sk_buff结构来表征;它的IP头&nbsp;<BR>会被做上标记以标识它是一个分块了的包,其中还包含分割偏移量。最后一&nbsp;<BR>个包被标识为最后IP单元。如果在分块过程中,IP不能分配sk_buff&nbsp;,则传&nbsp;<BR>输失败。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;接收IP分块单元要比发送它们要麻烦一些,因为这些IP单元可能以任何&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -