
部分信息参考 中国石油大学 信息安全实验 信息安全实验四实验参考 参考 信息安全实验资料 四个PPT文件 server.cLinux系统的套接字可以支持多种协议,每种不同的协议都是用不同的地址结构。 在头文件中定义了一个通用套接字地址结构sockaddr:为了处理struct sockaddr,程序员创造了一个并列的大小相等结构:struct sockaddr_in(“in”代表”Internet”。) struct sockaddr_in在/usr/include/netinet/in.h中定义:填充特定协议地址时使用sockaddr_in 作为bind()、connect()、sendto()、recvfrom()等变量的参数时必须使用sockaddr, 这时应借助指针强制转化的方法转为struct sockaddr 指针。
inet_aton():将字符串形式的IP地址转换成二进制形式的IP地址,成功返回1,否则返回0,转换后的IP地址存储在参数inp中。 inet_ntoa():将32位二进制形式的IP地址转换为数字点方式的IP地址,结果在变量返回值中返回。字节序,顾名思义字节的排序,就是大于一个字节的数据在存储中的储存顺序。 在跨平台以及网络程序应用中字节序才是一个应该被考量的弊端。 网络字节序是TCP/IP规定的一种数据表示格式,与准确的CPU类型、操作系统无关,从而可以确保数据在不同主机之间存储时可被恰当解释。网络字节排序采用big endian(大端字节序)。 Intel x86系列CPU使用的都是little endian(小端字节序) 大端字节序(big-endian):低地址存放最高有效字节 小端字节序(little-endian):低地址存放最低有效字节 例如数字0x12345678(DWORD)在两种不同字节序CPU中的存储顺序如下所示:下面四个函数分别用于长整型和短整型数在网络字节序和主机字节序之间进行转化,其中s指short,l指long,h指host,n指network如果是应用层的数据,即对TCP/IP来说是透明的数据,不用考虑字节序的问题。

因为接收端收到的排序是跟发送端一致的 但针对TCP/IP的IP地址、端口号来说就不一样了,例如由于网络字节序是big endian,即低地址存放的是数值的高位,所以TCP/IP实际上把这个port解释为0x1200(十进制4608)。 本来准备是应在端口18建立联结的,但TCP/IP协议栈却在端口4608建立了联结INET 套接字就是支持 Internet 地址族的套接字,它位于TCP协议之上,BSD套接字之下, 如图所示,这里也表现了Linux网络模块分层的设计思想(图在PPT里,自己想象吧…) INET和 BSD 套接字之间的接口通过 Internet 地址族套接字操作集实现,这些操作集实际是一组协议的操作例程, 在include/linux/net.h中定义为proto_ops:这个操作集类似于文件系统中的file_operations结构。
BSD套接字层通过读取proto_ops 结构中的相应函数执行任务。 BSD套接字层向 INET 套接字层传递socket数据结构来代表一个BSD套接字,socket结构在include/linux/net.h中定义:但在INET套接字层中,它运用自己的sock数据结构来代表该套接字,因此,这两个结构之间存在着链接关系 Sock结构定义于include/net/sock.h(此结构有80多行,在此不予列出 在BSD的socket数据结构中存在一个指向sock的指针sk,而在sock中既有一个指向socket的指针, 这两个指针将BSD socket数据结构和sock数据结构链接了出来。 通过这些链接关系,套接字调用就可以便于地检索到sock数据结构 实际上,sock数据结构可适用于不同的地址族,它也定义有自己的协议操作集proto 进程在借助套接字进行通信时,采用用户-服务器模型。服务器首先建立一个套接字,并将某个名称绑定到该套接字上,套接字的名称依赖于套接字的底层地址族,但一般是服务器的本地地址对于INET套接字来说,服务器的地址由两部分构成:服务器的IP地址和服务器的端口地址。

已登录的标准端口可查看/etc/services 文件 将地址绑定到套接字之后,服务器就可以请求连接该绑定地址的传入连接 连接请求由用户生成,它首先创建一个套接字,并选定服务器的目标地址以请求设立连接 传入的联接请求通过不同的协议层到达服务器的套接字 服务器接收到传入请求后,如果无法接受该请求,服务器必须建立一个新的套接字来接受该请求并成立通讯连接(用于的套接字不能用来创建通讯连接),这时,服务器和用户就可以运用建立好的通讯连结传输数据 BSD套接字上的详细操作与准确的底层地址族有关,底层地址族的不同实际意味着寻址模式、采用的协议等的不同 Linux 利用BSD套接字层抽象了不同的套接字接口。在内核的初始化阶段,内建于内核的不同地址族分别以BSD套接字接口在内核中登录 然后,随着应用程序创建并使用BSD套接字 内核负责在BSD套接字和底层的地址族之间构建联系。这种联系通过交叉链接数据结构以及地址族专有的支持例程表创建 在内核中,地址族和协议信息保存在inet_protos向量中,其定义于include/net/protocol.hLinux在利用socket()系统读取建立新的套接字时,需要传递套接字的地址族标识符、套接字类型或者协议,其变量定义于net/socket.c中实际上,套接字对于用户程序而言就是特殊的已开启的文件。
内核中为套接字定义了一种特殊的文件种类,形成一种特殊的文件系统sockfs 所谓创建一个套接字,就是在sockfs文件系统中建立一个特殊文件,或者说一个节点,并成立起为推动套接字功能所需的一整套数据结构 所以,函数sock_create()首先是创建一个socket数据结构,然后将其“映射”到一个已开启的文件中,进行socket结构和sock结构的分配和初始化 实际上,socket结构与sock结构是同一事物的两个方面。如果说socket结构是面向进程跟系统读取介面的,那么sock结构就是面向底层驱动程序的 把与文件系统关系非常紧密的那一部分放在socket结构中,把与通信关系非常紧密的那一部分则单独构成一个数据结构,即sock结构 由于这两个别数据在逻辑上原本就是一体的,所以应借助指针互相指向他人,形成的关系为了传入的Internet 连接请求,每个服务器都必须建立一个INET BSD套接字,并且将自己的地址绑定到该套接字 将地址绑定至某个套接字上后来c 网络编程基础,该套接字就不能用来进行任何其它的通信,因此,该socket数据结构的状态需要为TCP_CLOSE 传递到绑定操作的sockaddr数据结构中包括要绑定的 IP地址以及一个可选的端口地址。

被绑定的IP地址保存在sock数据结构的rcv_saddr和 saddr域中,这两个域分别用于哈希查找和发送用的IP地址。 端口地址是可选的,如果没有指定,底层的支持网络会选择一个空闲的端口 当底层网路设备接受到数据包时,它需要将数据包传递到恰当的 INET 和 BSD 套接字以便进行处理,因此,TCP维护多个哈希表,用来查找传入 IP 消息的地址,并将他们定向至恰当的socket/sock 对 TCP 并不在绑定过程中将绑定的sock数据结构添加到哈希表中,在这一过程中,它只是判断所请求的端口号当前是否正在使用。在操作中,该 sock 结构才被添加到 TCP 的哈希表中构建一个套接字之后,该套接字不仅可以用于入站的连接请求c 网络编程基础,也可以用于构建出站的联结请求。不论如何都涉及到一个重要的过程:建立两个应用程序之间的虚拟电路。出站连接只能建立在进入正确状态的 INET BSD 套接字上, 因此,不能建立于未完善连接的套接字,也不能建立于用于入站联接的套接字。也就是说,该 BSD socket 数据结构的状态需要为 SS_UNCONNECTED 在构建连接过程中,双方 TCP 要进行三次“握手”。
如果 TCP sock 正在等待传入消息,则该 sock 结构添加到 tcp_listening_hash 表中,这样,传入的 TCP 消息就可以定向到该 sock 数据结构当某个套接字被绑定了地址以后,该套接字就可以用来专属于该绑定地址的传入连接。网络应用程序也可以在未绑定地址之前套接字,这时,INET 套接字层将借助空闲的端口编号并手动绑定到该套接字。套接字的函数将 socket 的状态改变为TCP_LISTEN 当接收至某个传入的 TCP 连接请求时,TCP 建立一个新的 sock 数据结构来表述该连接。当该连接最后被接受时,新的 sock 数据结构将成为该 TCP 连接的内核bottom_half部分,这时,它应克隆包含连接请求的传入 sk_buff 中的信息,并在 sock 数据结构的 receive_queue 队列中将克隆的信息排队。克隆的 sk_buff 中包括有指向新 sock 数据结构的指针接受操作在套接字上进行,从 socket 中克隆一个新的 socket 数据结构。其过程如下: 接受操作首先释放到支持协议层,即INET中,以便接受任何传入的连接请求。

接受操作可以是阻塞的或是非阻塞的。非阻塞时,若没有可接受的传入连接,则接受操作将失败,而新创建的socket数据结构被放弃。阻塞时,执行阻塞操作的网络应用程序将添加至等待队列中并维持挂起直到接收至一个TCP连接请求为止。 当连接请求前往但是,包含连接请求的sk_buff被丢掉,而由TCP建立的新sock数据结构返回到INET套接字层,在这里,sock数据结构和当时创建的新socket数据结构建立链接。而新socket的文件描述符(fd)被返回至网络应用程序,此后,应用程序就可以借助该文件描述符在新建立的INET BSD套接字上进行套接字操作见PPT 3.7getsockname(): 获取与当前套接字绑定的IP地址及端口返回值:成功返回0,失败返回-1,并在errno中设定错误代码。 错误代码:返回值:成功返回0,失败返回-1,并在errno中设定错误代码。
错误代码:gethostbyname():主机名转换为IP地址 gethostbyaddr():IP地址转换成主机名getservbyname():根据给定名字查找相应服务,返回服务的端口号 getservbyport():给定端口号和可选协议查找相应服务套接字地址是多字节数据,不是以空字符结尾的,Linux提供两组函数来处理多字节数据。一组函数以b开头,适合BSD平台兼容的函数;另一组函数以mem开头,是ANSI C提供的变量函数bzero将参数s指定的内容的前n个字节设定为0,通常用它来将套接字地址清零 函数bcopy从参数src指定的存储区域拷贝指定数量的字符内容到参数dest指定的存储区域 函数bcmp比较参数s1指定的存储区域和参数s2指定的存储区域的前n个字节内容,相同则返回0,否则返回非0 将参数s指定的存储区域的前n个字节设定为参数c的内容 类似于bcopy,但bcopy能处理参数src和参数dest所选定的区域有重合的状况,而memcpy不能 比较参数s1和参数s2指定区域的前n个字节内容,相同则返回0,否则返回非0套接字标识TCP/IP的连接 使用套接字要切记: 1、sockaddr与sockaddr_in的区别 2、网络字节排序 了解套接字的工作原理 掌握套接字的通信过程
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-142940-1.html
我不动
难喝要死
人民必胜