📄 00000011.htm
字号:
X25 <BR> X25 <BR> <BR> <BR> 有一些套接字类型支持面向连接的服务类型。并非所有的地址族能支持 <BR>所有的服务类型。LinuxBSD 套接字支持下列套接字类型: <BR> <BR>Stream <BR> 这些套接字提供可靠的双工顺序数据流,能保证传送过程中数据不丢失, <BR> 不被弄混和复制。Internet地址中的TCP协议支持流套接字。 <BR>Datagram <BR> 这些套接字提供双工数据传送,但与流套接字不同,这里不保证信息 <BR> 的到达。即使它们到达了,也不能保其到达的顺序,甚至不能保证被复 <BR> 制和弄混。这类套接字由Internet地址族中的UDP协议支持。 <BR>Raw <BR> 允许直接处理下层协议(所以叫“Raw”)。例如,有可能打开一个raw套 <BR> 接字到以太网设备,看raw IP数据传输。 <BR>Reliable Delivered Messages <BR> 与数据报很象,但它能保证数据的到达。 <BR>Sequenced Packets <BR> 与流套接字相似,但的数据包大小是固定的。 <BR>Packet <BR> 这不是一个标准的BSD套接字类型,而是一个Linux特定的扩展,它允许 <BR> 在设备级上直接处理包。 <BR> <BR> 客户服务器模式下使用套接字进行通信。服务器提供一种服务,客户使 <BR> 用这种服务。Web服务器就是一个例子,它提供网页,而客户端,或者说 <BR> 浏览器,来读这些网页。服务器要使用套接字,首先要建立套接字并将它 <BR> 与一个名称绑定。名称的格式由套接字的地址族来定,是服务器的本地有 <BR> 效地址。套接字的名称或地址用结构sockaddr来指定。一个INET套接字还 <BR> 与一个端口地址绑定。已注册的端口号可在/etc/services中找到;例如, <BR> Web服务的端口号是80。将套接字与地址绑定以后,服务器不可以监听指 <BR> 定的绑定了的地址上的引入连接请求。请求的发起者,客户端,建立一个 <BR> 套接字并通过它来发出一个连接请求到指定的目标服务器地址。对于一个 <BR> INET套接字,服务器地址是它的IP地址和它的端口号。这些引入请求必须 <BR> 通过各种协议层找到目的地址,然后等待服务器的监听套接字。服务器收 <BR> 到引入请求后可以接收或拒绝它。如果决定接收,服务器必需建立一个新 <BR> 一套接字来接收请求。当一个套接字被用来监听引入连接请求时,它就不 <BR> 能用来支持连接了。连接建立后两端就可以自由地发送和接收数据了。最 <BR> 后,当不再需要连接时,就将之关闭。要注意保证在传输过程正确处理数 <BR> 据包。 <BR> <BR> 对BSD socket进行准确操作要依赖于它下面的地址族。设置TCP/IP连接与 <BR>设置amateurradio X.25连接有很大不同。象虚拟文件系统一样,Linux从BSD <BR>socket层抽象出socket接口,应用程序和BSD socket由每个地址族的特定软件 <BR>来支持。内核初始化时,地址族被置入内核中并将自己注册到BSD socket接口。 <BR>之后,当应用程序建立用使用BDS sockets时,在BSDsocket与它支持的地址族 <BR>之间将产生一个联接。这一联接是由交叉链接数据结构和地址族表特定支持程 <BR>序产生。例如,每当应用程序建立一个新的socket,就会有一个BSD socket接 <BR>口用的地址族特定 socket建立程序。 <BR> <BR> 构造内核时,一些地址族和协议被置入 protocols向量。每个由它的名称 <BR>来表征,例如,“INET”和它的初始程序地址。当套接口启动时被初始化时, <BR>要调用每一协议和初始程序。对socket地址族来说,这会导致它们注册一套协 <BR>议操作。这是一套例程,其中的每一例程执行一个特定的针对那一地址族的操 <BR>作。已注册的协议操作被存在pops 向量,一个指向 proto_ops 数据结构的向 <BR>量中。 <BR> <BR> proto_ops结构由地址族类型和一系列指向与特定地址族对应的socket操 <BR>作例程的指针组成。pops向量通过地址族标识符来索引,如Internet地址族 <BR>标识符(AF_INET是2)。 <BR> <BR> <BR> <BR>10.4 INET Socket 层 <BR> <BR> INET socket层支持包括TCP/IP协议在内的internet地址族。如前所述, <BR>这些协议是分层的,一个协议使用另一个协议的服务。Linux的TCP/IP代码和 <BR>数据结构反映了这一分层模型。它与BSD socket层的接口要通过一系列Internet <BR>地址族socket操作,这一操作是在网络初始化时就已经注册到BSD socket层的。 <BR>这些都与其它已注册的地址族一起保存在 pops 向量中。BSD socket层从已注 <BR>册的INET proto_ops 数据结构中调用INET层socket支持例程来为它执行工作。 <BR>一个地址族为INET的BSD socket建立请求,将用到下层的INET socket的建立 <BR>函数。在这些操作中,BSD socket层把用来描述BSD socket的 socket 结构传 <BR>构到INET层。为了不把BSD socket 与TCP/IP的特定信息搞混,INET socket层 <BR>使用它自己的数据结构,sock,它与BSD socket 结构相连。这一联接关系可以 <BR>看出。它用BSDsocket的 data 指针来连接 sock 结构与BSD socket结构。这意 <BR>味着后来的INETsocket调用能够很容易地重新找到 sock 结构。 sock结构的协 <BR>议操作指针也在初始化时建立,它依赖与被请求的协议。如果请求的是TCP,那么 <BR>sock 结构的协议操作指针将指向TCP连接所必需的TCP协议操作集。 <BR> <BR>10.4.1 建立BSD socket <BR> <BR> 系统建立一个新的socket时,通过标识符来确定它的地址族,socket类型和协议。 <BR> <BR> 首先,从 pops向量中搜索与被请求的地址族相匹配的地址族。它可能是一 <BR>个作为核心模块来实现的一个特定的地址族,这样,在其能继续工作前,kerneld <BR>守护进程必须加载这一模块。分配一个新的 socket 结构来代表BSD socket。实 <BR>际上 socket 结构是 VFS inode结构的一部分,分配一个socket实际上就是分配 <BR>一个 VFS inode。除非你认为socket操作能和普通的文件操作一样,否则会觉得 <BR>这好象很奇怪。所有的文件用VFSinode结构来表示,为了支持文件操作,BSD <BR>socket必须也用 VFS inode来表示。 <BR> <BR> 最新建立的 BSD socket结构包含一个指向地址族特定socket例程的指针, <BR>可以用来从 pops 向量中找到proto_ops结构。它的类型被设置成被请求的socket <BR>类型:SOCK_STREAM,SOCK_DGRAM等等之一。调用地址族特定创建例程使用保存在 <BR>proto_ops 结构中的地址。 <BR> <BR> 从当前过程 fd 向量中分配一个自由的文件描述符,对 file结构所指向的 <BR>进行初始化。包括将文件操作指针设置为指向由BSDsocket接口支持的BSD socket <BR>文件操作集。任何操作将被引到socket接口,通过调用它的地址族操作例程将它们 <BR>传到支持的地址族。 <BR> <BR>10.4.2 将地址与INET BSD socket绑定 <BR> <BR> 为了能监听输入的internet连接请求,每个服务器必须建立一个INET BSD <BR>socket,并将地址与其绑定。绑定操作主要在INET socket层内处理,下面的TCP <BR>和UDP协议层提供一些支持。与一个地址绑定了的socket不能用来进行任何其它的 <BR>通讯工作,也就是说:socket的状态必须是TCP_CLOSE 。 sockaddr结构包含了 <BR>与一个任意的端口号绑定的IP地址。通常绑定的IP地址已经分配给了一个网络设 <BR>备,该设备支持INET地址族且其接口是可用的。可以在系统中用ifconfig命令来 <BR>查看哪一个网络接口是当前激活的。IP地址也可以是广播地址,全1或全0。这是 <BR>些特定的地址,用以表示发送给任何人3。如果机器充当一个透明的代理或防火 <BR>墙,则IP地址可被指定为任一个IP地址,但只有有超级用户权限的进程能绑定到 <BR>任何一个IP地址。绑定的IP地址被存在sock结构中的recv_addr 和 saddr字段。 <BR>端口号是可选的,如果没有指定,将任意指定一个。按惯例,小于1024的端口号 <BR>不能被没有超级用户权限的进程使用。如果下层网络没有分配端口号,则分配一 <BR>个大于1024的端口号。 <BR> <BR> 下层网络设备接收的包必须由经正确的INET和BSD socket才能被处理。因此, <BR>UDP和TCP维护了一些hash表用来在输入IP消息内查找地址并将它们导向正确的 <BR>socket/sock对。TCP是一个面向连接的协议,因而涉及处理TCP包的信息比用于处 <BR>理UDP包的信息多。 <BR> <BR>UDP维护着一张已分配UDP端口表, udp_hash 表。由指向 sock数据结构的指针 <BR>组成,通过一个基于端口号的hash函数来索引。UDPhash表比允许的端口号的数 <BR>目小得多(udp_hash为128 或者说是 UDP_HTABLE_SIZE )表中的一些项指向一 <BR>个 sock结构链,该链用每个 sock 结构中的 next 指针来将每个 sock 连接起来。 <BR> <BR> TCP是十分复杂的,它包括几个hash表。但实际上TCP在绑定操作时没有将 <BR>sock 结构与其hash表绑定,它仅仅检查被请求的端口号当前没被使用。 sock <BR>结构是在 listen 操作时被加入TCP的hash表的。 <BR> <BR>复习提要: What about the route entered? <BR> <BR>10.4.3 在INET BSD Socket上建立连接 <BR> <BR> 建立一个socket,如果没有用它来监听连入请求,那么就能用它来发连出请 <BR>求。对于面向无连接的协议如UDP来说,这一socket操作并不做许多事,但对于面 <BR>向连接的协议如TCP来说,这一操作包括了在两个应用间建立一个虚连接。 <BR> <BR> 一个连出连接操作只能由一个在正确状态下的INET BSD socket来完成;换句 <BR>话说,socket不能是已建立连接的,并且有被用来监听连入连接。这意味着BSD <BR>socket 结构必须是 SS_UNCONNECTED状态。UDP协议没有在两个应用间建立虚连接, <BR>任何发出的消息都是数据报,这些消息可能到达也可能不到达目的地。但它不支持 <BR>BSD socket的 connect 操作。建立在UDP的INET BSD socket上的连接操作简单地 <BR>设置远程应用的地址:IP地址和IP端口号。另外,它还设置路由表入口的cache以 <BR>便这一BSD socket在发用UDP包时不用再次查询路由数据库(除非这一路由已经无 <BR>效)。INET sock 结构中的 ip_route_cache指针指向路由缓存信息。如果没有给 <BR>出地址信息,缓存的路由和IP地址信息将自动地被用来发送消息。UDP将sock 的状 <BR>态改为 TCP_ESTABLISHED 。 <BR> <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -