TCPIP与socket编程.ppt_第1页
TCPIP与socket编程.ppt_第2页
TCPIP与socket编程.ppt_第3页
TCPIP与socket编程.ppt_第4页
TCPIP与socket编程.ppt_第5页
已阅读5页,还剩51页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第3讲TCP/IP实现 与Socket编程,3.1.1 Linux下TCP/IP框架,3.1.1.1 Linux下TCP/IP实现结构,分析Linux下TCP/IP的实现,其目标在于让学生通过阅读源代码,对经典的TCP/IP协议实现有所了解,提高对网络编程的认识和理解。 阅读Linux网络内核代码是一件繁琐而起枯燥无味的工作,但是当你对TCP/IP协议的实现有了一定了解的时候,你会发现所有的辛苦都是值得的。,Linux用一系列相互连接层的软件实现TCP/IP协议族,该套软件分为两个层次,分别为BSD套接字(BSD sockets)与INET套接字(INET sockets)。,套接字又称为管套

2、,是网络上运行的两个程序之间的双向通信链路中的端点,而应用程序通过套接字使用通信链路提供的服务。因此,套接字是一个编程接口,为网络应用程序提供各种接口函数。,3.1 TCP/IP源代码概述,BSD套接字是UNIX为网络编程提供的传输层编程接口,该接口并不考虑底层的网络通信协议,而是在所有的通信协议之上提供统一的接口函数。因此,不管编程用户使用何种底层网络协议,所使用的BSD套接字函数都是一致的。,INET套接字是BSD套接字基于TCP/IP协议的底层实现,将TCP/IP协议提供的各种服务封装成INET套接字函数,再实现统一的BSD套接字函数。,其 他 底 层 套 接 字 及 协 议,其 他 底

3、 层 套 接 字 及 协 议,BSD文件套接字 INET网络套接字,3.1.1.2 BSD Socket接口,BSD套接字是UNIX为网络编程提供的统一传输层编程接口,支持多种底层网络通信协议。,套接字地址族,每种网络协议都有自己的网络地址,被称为地址族。,套接字类型,Stream :这些套接字提供可靠的双工顺序数据流,能保证传送过程中数据不丢失,不被混淆和复制。Internet地址中的TCP协议支持流套接字。 Datagram :这些套接字提供双工数据报传送,但与流套接字不同,不保证信息的到达,也不能保其到达的顺序,甚至不能保证被复制和混淆。这类套接字由Internet地址族中的UDP协议支

4、持。 Raw :允许直接处理下层协议。例如,可以通过raw套接字直接访问IP数据包。 Reliable Delivered Messages :与数据报类似,但能保证数据的到达。 Sequenced Packets :与流套接字相似,但的数据包大小是固定的。 Packet :packet不是一个标准的BSD套接字类型,而是一个Linux特定的扩展,它允许在设备级上直接处理数据包。,套接字类型的划分,实际上是服务类型的划分。,在不同的协议族中,具有各种不同性能、特色的传输层、网络层协议。在进行网络编程中,用户无需考虑具体的协议细节,仅仅知道该协议可以提供何种类型的服务。,下面是现实网络协议中,可

5、能与BSD Socket类型相匹配的网络协议。,Stream类型套接字TCP/IP协议族中的TCP协议,Datagram类型套接字TCP/IP协议族中的UDP协议,TCP协议采用字节编码 双向连接 拥有校验与确认机制 TCP包大小不固定,UDP协议不采用编码 双向无连接 有包头校验 无确认机制 UDP包大小不固定,Raw类型套接字TCP/IP协议族中的网络层协议以及底层协议,IP协议 ICMP协议 IGMP协议 ARP协议 RARP协议,Reliable Delivered Messages类型套接字帧中继协议中的数据链路帧传输,双向传输 有确认协议 数据分帧传输 帧传输不能保证顺序,Sequ

6、enced Packets类型套接字ATM协议中的信元传输,采用虚电路方式 信元大小固定 保证信元顺序达到 有校验和确认机制,套接字文件系统,在Unix中,所有的外部设备都是以虚拟文件的形成存在,用户对设备的访问是通过对虚拟文件的访问实现的。用户输出数据,就是向虚拟文件执行写操作;用户获取输入数据,可以通过从文件读来实现。 在Linux中,套接字文件系统是一个用户不可见的,高度简化的,用于汇集网络套接字的内存文件系统;它没有块设备、没有子目录、没有文件缓冲,借用虚拟文件系统的框架来使套接字与文件描述字具有相同的用户接口;程序员通过套接字文件系统可以像访问文件中的数据一样访问网络数据。,Linu

7、x中,所有的文件都用VFS inode结构来表示,为了支持文件操作,BSD socket必须也用 VFS inode来表示。 socket 结构是 VFS inode 结构的一部分,分配一个socket实际上就是分配一个 VFS inode。 网络程序涉及到两种套接字文件套接字与网络套接字。用户访问文件套接字,而系统使用网络套接字。两者之间一一对应,通过指针实现对应关系,对文件套接字的操作将直接映射为网络套接字的操作。 socket()函数用于创建文件套接字,用sokcet结构表示,其操作表为socket_file_ops,它指向操作函数集合proto_ops;网络套接字用sokc结构表示,将

8、根据使用的协议,使操作函数指向特定的协议操作。 在TCP/IP协议族中: SOCK_STREAM类型的文件套接字操作表为inet_stream_ops,其默认协议为TCP,在不做改变时网络套接字操作表为tcp_prot; SOCK_DGRAM类型的文件套接字操作表为inet_dgram_ops,其默认协议为UDP,网络套接字操作表为udp_prot; SOCK_RAW类型的文件套接字操作表为inet_dgram_ops,其默认协议为IP,网络套接字操作表为raw_prot;,用户访问的文件,用户访问的一个文件,VFS inode文件套接字,网络套接字,3.1.2 Linux下TCP/IP启动,

9、inet_create()把协议的操作集赋给socket sock_init_data()建立socket和sock的关联 tcp_v4_hash()将sock对象注册到散列表tcp_ehash中,以便以后查找 register_filesystem()注册套接字文件系统 kern_mount()安装套接字文件系统 tcp_v4_init_sock()将设置具体的TCP协议信息,3.1.3 各种数据结构,socket结构 proto_ops结构 sock结构 proto结构 sockaddr结构 sockaddr_in结构,3.1.3.1 常见数据结构,左图以使用TCP协议的程序为例,展示了各

10、种数据结构之间的关系。,3.1.3.2 核心数据结构sk_buff,在Linux的网络代码中,所有协议层次之间通过一种特殊的数据结构实现数据交换。 众所周知,网络协议都采用层次结构,在ISO/OSI中,我们已经学习过三种特殊的数据单元。 PDU、SDU、IDU,其中SDU与PDU之间的关系最为重要。,PCI(n),+,SDU(n),=,PDU(n),在IP Over Ethernet中,TCP/IP协议族各层的协议数据单元之间的关系如下。,Linux没有采用在各层之间通过数据包复制的方法实现各层次之间的数据传递,而是通过直接将数据包加入层次队列的方法实现,保证了协议数据包处理的快捷和高效。 L

11、inux采用一种数据结构sk_buff在不同协议层及网络设备驱动程序之间传送数据,也就是说,网络设备发送与接收数据包所用的缓冲区是一个统一的数据结构sk_buff,并且这些结构一旦在内核中产生,无论在任何层次间传递,都始终保持有效,直至消亡。(注:sk_buff只在操作系统的内核空间中出现) 在使用sk_buff结构时,该结构链接到一个双向循环链表中,双向循环链表的作用在于很方便地实现插入与删除,这是Linux实现网络数据缓冲区的主要方式。,sk_buff结构,sk_buff结构在“include/linux/skbuff.h”中定义。,struct sk_buff struct sk_buf

12、f* next; struct sk_buff* prev; struct sk_buff_head * list; /*以上三个变量将sk_buff链接到一个双向循环链表中,*/ struct sock*sk; /*此报文所属的sock结构,此值在本机发出的报文中有效,从网络设备收到的报文此值为空。*/ struct timevalstamp;/此报文收到时的时间 struct device*dev;/收到此报文的网络设备,union struct tcphdr*th; struct udphdr*uh; struct icmphdr*icmph; struct igmphdr*igmph;

13、 struct iphdr*ipiph; struct spxhdr*spxh; unsigned char*raw; h; union struct iphdr*iph; struct ipv6hdr*ipv6h; struct arphdr*arph; struct ipxhdr*ipxh; unsigned char*raw; nh; union struct ethhdr*ethernet; unsigned char *raw; mac;,左边三个union结构依次是传输层,网络层,链路层的头部结构指针。这些指针在网络报文进入这一层时被赋值,其中raw是一个无结构的字符指针,用于扩展

14、的协议。,协议的层次性导致了协议头的层次性,一个ks_buff结构可以选择不同的协议头,从而实现网络数据包属于不同的协议数据单元。,unsigned int len; /*此报文的长度,这是指网络报文在不同协议层中的长度,包括头部和数据。在协议栈的不同层,这个长度是不同的。*/ unsigned int data_len; /*这个变量记录的是在frags和frag_list里面存储的报文的长度。*/ unsighed inttrue_size; /*truesize是sk_buff用来存放数据的缓冲区的长度,并不是指有效数据的长度。*/ unsigned char*head;/指向被分配的内

15、存空间的首地址 unsigned char*data;/指向当前数据包的首地址 unsigned char*tail;/指向当前数据包的末地址 unsigned char *end; /指向被分配的内存空间的末地址 /*以上四个变量指向此报文存储区。*/,四个指针变量,报文的存储空间是在网络设备收到网络报文或者应用程序发送数据时分配的,分配的空间是16字节的倍数。 分配空间后,将网络报文填充到这个存储空间中去。填充时先在存储空间的头部预留一定数量的空隙,然后将网络报文放到剩余的空间中去。,head指针指向存储空间的起始地址; end指针指向存储空间的结束地址 ; data指针指向网络报文的起始

16、地址 ; tail指针指向网络报文的结束地址。,在新内核Linux2.4.x中,网络报文在内存中不一定是连续存储的,同一个网络报文有可能被分成几片存放在内存的不同位置。,frags是一个数组,frag_list是一个单向链表,它们所指向的存储空间是一个页的大小(即4k)。这些额外的存储空间并不是一开始就使用的,只有在data所指的存储空间不够用的情况下才使用这些存储空间。 在sk_buff里增加了一个变量data_len。这个变量记录的是在frags和frag_list里面存储的报文的长度。 在较早的版本中: skb-len = skb-tail skb-data skb-turesize =

17、skb-end skb-head 在2.4.X内核中: skb-len = skb-tail skb-data skb-data_len skb-turesize =skb-end skb-head + skb-data_len,sk_buff_head的定义,网络协议栈的实现中,需要把许多网络报文放到一个队列中做异步处理,Linux定义了数据结构sk_buff_head。这是一个双向链表的头,它把sk_buff链接成一个双向链表。,关于sk_buff与sk_buff_head的操作函数,见课本。,在Linux中,所有的外围设备被归结为三类:字符设备、块设备和网络设备; Linux对所有的物理

18、网络设备进行抽象并定义了统一的概念接口; 一个网络接口被看作是一个发送和接收数据包的实体; 对于每个网络接口,都用一个net_device的数据结构表示。,3.2.1 网卡驱动程序概述,3.2 Linux网卡驱动程序分析,发送数据时,系统根据路由表选择相应的网络接口进行数据传输; 接收数据时,通过驱动程序登记的中断服务程序进行数据的接收处理。,Linux网络驱动程序的体系结构可以划分为四层: 协议接口层 网络设备接口层 设备驱动功能层 网络设备和网络媒介层,介绍一下Linux对网络接口的命名方式。,3.2.2 网卡初始化,网络设备的初始化主要工作是检测设备的存在、初始化net_device结构

19、及在系统中登记该设备。,由shell命令“insmod”触发的模块化驱动程序; 系统驱动时由核心自动检测网络设备并进行初始化。,系统初始化,模块初始化,网络设备的初始化从触发角度看可分为两类:,3.2.3 数据包的发送与接收,物理网络设备接收到数据时,系统可以通过两种途径读取数据:,轮循方式 中断方式,中断方式利用硬件体系结构的中断机制实现设备和系统的应答对话,即当物理设备需要CPU处理数据时,设备就发一个中断信号给系统,系统则在收到信号后调用相应的中断服务程序响应对设备中断的处理。,网卡即网络适配器,作为一种I/O接口卡插在主机板和数据总线的扩展槽上,是网络通信的主要瓶颈之一。 网卡的作用是

20、实现介质访问控制协议,为逻辑链路控制层提供服务。,Realtek 8139硬件结构和控制逻辑,LAN管理部分和微处理器 曼彻斯特编译码器 发送和发送控制部分 接收和接收控制部分,网卡主要由以下几个部分组成:,在LAN管理部分中包含先进先出存储器(FIFO) 与DMA控制器 。,FIFO存储器是用来在通过系统总线传送数据到系统存储器之前缓存从LAN上接收到的数据; DMA控制器则用于在高度优化的总线结构中提供对系统存储器的可靠访问。,数据的发送与接收的具体过程见课本。,3.3 IP协议分析与编程,网际协议IP(Internet Protocol)是TCP/IP体系中最主要的协议之一,它工作于网络

21、层。与IP协议配套使用的还有两个协议: Internet控制报文协议ICMP(Internet Control Message Protocol) Internet 组管理协议IGMP( Internet Group Management Protocol ),3.3.1 IP基础知识,IP地址划分 IP地址与MAC地址 IP子网划分 IP路由策略最佳匹配 IP数据包格式,3.3.2 Linux中IP协议分析,3.3.2.1 IP协议构成,IP协议主要完成的任务:,确定要接收或发送数据的路由对于发送数据寻找合适的路由;对于接收的数据包,如果目的地是本机地址,则传送到上层传输层,否则寻找合适路由

22、进行转发。 数据包的封装与解封对传输层发送过来的数据包加上IP报头部;对物理层发送过来的数据包则要去除IP层下层的协议的头部。 数据包的分割与重组发送数据时,对需要分组的IP报文进行分组;接收数据时,对需要重组的IP报文分片进行重组。,ip_input.c 处理到达本主机的包; ip_output.c 处理离开本主机的包; ip_forward.c 处理被本机路由的包; ip_fragment.c 用于IP报文的分割; ip_options.c 用于处理IP选项; ip_multicast.c 用于处理多播传送;,主要的源代码文件:,IP数据包的收发过程,3.3.2.2 IP源代码分析,这部分

23、内容是一批研究生通过多个假期,进行源代码分析,收集了大量来自于互联网络的资料,经过整理而成。 同时,每年都有一批本科毕业生,会加入对源代码进行分析的工作,并借此提升自己对网络功能的了解。 希望这个工作一直继续下去,并在同学们中间形成一种阅读Linux网络代码的热潮,同时希望同学们能够做到互相学习、共同探讨、一起进步。,按照书本内容进行讲解,3.3.3 IP协议编程,3.3.3.1 Unix编程方法与环境,推荐工具书Linux编程宝典电子工业出版社,Linux下编辑器,Linux下流行的编辑器有vi和Emacs,其中vi的编辑命令复杂,而Emacs采用IDE方式,使用较为简单,同时该软件拥有Xw

24、indows界面下的Xemacs,支持图形化界面。,推荐使用Windows平台下的Linux模拟环境Cygwin,安装方法见下发的光盘。 使用Linux下的Xwindows应用程序,需要配置安装配置winaxeplus等Xterm软件。,Linux下C开发环境,在Linux环境下进行开发工作时,大量的工作将以C开发环境为中心,即gcc。gcc是GNU C Compiler的缩写,是GNU/Linux系统下的标准C编译器。,通过gcc对C程序文件进行编译的格式 # gcc test.c /gcc将产生一个名为test.out的可执行文件,运行程序员在test.c中编写的程序 参数:-o 修改输出

25、文件名 # gcco test test.c /编译test.c,将输出可执行程序的名字改为test,gcc,参数:-W 获取警告信息 # gccWall test test.c /编译test.c,输出所有警告信息 # gccWerrorl test test.c /编译test.c,将所有警告信息作为错误处理 参数:-0 优化编译,分为三个等级,优化程度越高,代码运行越快,代码大小就越大 # gcc01 test test.c /编译test.c,以第一级别优化,默认优化 参数:-g 产生调试标记,利于gdb调试 # gccg test test.c /编译test.c,gcc在可执行程序

26、与目标文件中插入额外信息,以便于发现源程序执行至哪一行出错,参数:-I 指定头文件所在的目录 # gccI/usr/include/myhead test.c /编译test.c,指出test.c中使用的在默认目录之外的头文件所在目录 参数:-L 指定库文件所在的目录 # gccL/usr/libinclude/mylib test.c /编译test.c,指出test.c中使用的在默认目录之外的库文件所在目录 gcc的其他高级参数见 Linux编程宝典,make,当程序变的越来越复杂实,对程序的处理也越来越复杂,Linux提供了GNUmake对程序项目进行管理。GNU make根据在Make

27、file文件中定义的规则进行程序处理,执行编译、汇编、连接等多种操作。 当获得了源程序及其Makefile文件后,运行“make”,GNU make将根据文件中的规则自动进行编译等操作。,Makefile文件中定义了三种类型的规则:,创建规则制定的文件; 指定形成最终可执行文件的必需过程; 指出每个文件的依赖性列表。,Makefile的实例:,all: myprogram Myprogram: io.o init.o compute.o gcc o myprogram io.o init.o compute.o compute.o: compute.c gcc Wall c o compute

28、.o compute.c init.o: init.c gcc Wall c o init.o init.c io.o: io.c gcc Wall c o io.o io.c,Makefile必须以Tab开头,如果采用空格,GNU make就无法识别; 在Makefile中,“:”符号表示左边的文件或选项依赖于右边的文件; GNU make通过依赖关系中文件的时间来判断是否需要进行重新编译; Makefile文件中可以定义变量,如“CC=gcc ”,也可以用$(变量名)来获取变量的值;,3.3.3.2 Raw套接字及其操作,BSD套接字用raw类型的套接字(又称为原始套接字)主要用于实现基于

29、ICMP、IGMP和IP协议的编程, 其主要的功能包括: 利用原始套接字可以进行ICMP、IGMP协议数据包的读写操作; 利用原始套接字可以进行IP包的读写操作。当IP的数据体部分是ICMP、IGMP、TCP、UTP协议数据包时,其IP包由系统内核自动进行处理的,而除此之外的协议,用户都可以进行IP数据包的操作; 利用原始套接字可以进行IP包头的构建操作,用于特殊IP包头的应用编程。,按书本内容进行利用原始套接字的各种函数介绍。 推荐工具书Linux网络编程清华大学出版社,3.3.3.3 IP编程实例讲解,3.4 TCP协议分析与编程,传输控制协议(TCP,Transmission Contr

30、ol Protocol)是TCP/IP协议族中最为重要、应用最为广泛的传输层协议,在Internet上,TCP协议可以提供面向连接的、可靠的字节流传输服务。,3.4.1 TCP基础知识,TCP协议特性,TCP报文与IP报文的关系,TCP协议使用时,采用“建立连接传输数据撤销连接”的固定模式; TCP连接是双向连接,连接两端的主机系统都拥有各自的发送缓冲区与接收缓冲区; TCP对数据报文中的每个字节都进行编号,被称为“字节流”; TCP提供了确认捎带机制和超时重传机制; TCP协议提供流量控制功能。,TCP首部,TCP建立与撤销连接,TCP数据流,交互式数据流与批量传输数据流,TCP定时器,重传

31、定时器当发送方发送数据后,会针对发送的报文产生一个重传定时器,如果在该定时器到期之前仍没有确认信息到来,则发送方会自动重传报文; 持续定时器主要用于在接收窗口关闭后,保持窗口大小信息的及时传递; 活性定时器主要用于检测连接是否处于活跃状态,如果在活性定时器到期之前,连接上没有任何信息发送,系统就认为另一端已经失效而主动关闭连接; 2MSL定时器该定时器主要用于关闭连接时,主机必须等待2 倍的数据报文最大存活时间(MSL)以便确认网络中不再存有任何该连接的数据报文。,3.4.2 Linux中TCP协议分析,3.4.2.1 TCP协议功能实现,进入内核态,在BSD Socket编程时,用户在用户态

32、使用BSD套接字函数编程,这些函数经过访管中断,进入管态,调用系统内核功能函数。,BSD Socket在进入管态后,调用函数sys_socketcall()进行功能调用。,asmlinkage long sys_socketcall(int call, unsigned long *args); 其中参数call表示调用的Socket功能号(宏),args为其参数表。,TCP的功能主要在“ipv4/tcp.c”中实现,查找Socket对象,大多数系统内核BSD函数中的第一个参数是一个文件句柄(file handle),用于查找相应的套接字对象。 查找socket对象的操作是调用sockfd_l

33、ookup()完成的,它先找到文件句柄对应的文件对象(file),然后取出文件对象对应的结点(inode),如果该结点是一个套接字结点,就找出对应的socket对象。,复制用户数据至内核空间,(1)使用move_addr_to_kernel()函数直接将sockaddr结构复制到内核空间中; (2)在发送与接收函数中,使用msghdr结构实现地址、用户缓冲区等数据在用户空间与内核空间之间的传递; (3)对于setsockopt()函数,不需要将用户数据保存到内核内存中。,Socket操作集与Sock操作集,socket结构与sock结构中有一个成员变量prot,都是指向一个函数集。只不过,so

34、cket结构中的ops指向的是INET Socket层的函数集,sock结构的prot指向的是更底层更具体操作的TCP函数集。,3.4.2.2 TCP状态,各状态的定义见书本,3.4.2.3 TCP通信模型,3.4.2.4 连接建立与撤销,3.4.2.5 数据发送与接收,这两部分按照书本内容进行讲解,3.4.3 TCP协议编程,3.4.3.1 服务器与客户机,服务器特性,监听套接字与连接套接字 服务器进程启动后需要绑定公共的服务端口 服务器可以在绑定提供服务的IP地址时,一般使用“INADDR_ANY” 设置监听套接字时,会指定一个未接受连接队列长度 服务器在接受连接时,一般会创建一个子进程或

35、线程 建立连接后,系统将以客户机的IP地址与端口号作为过滤条件,满足条件的数据才能转发给通信套接字,客户机特性,客户机没有监听套接字与连接套接字之分 客户机进程不需要绑定端口与IP地址,一般由系统自行分配 客户机套接字一旦建立连接后,只接受来自服务器IP地址与端口的数据,3.4.3.2 TCP套接字操作,3.4.3.3 TCP编程实例,以上内容按书本进行讲解,3.5 UDP协议分析与编程,用户数据报协议(UDP,User Datagram Protocol)是TCP/IP协议族中的一个传输层协议,它提供一种基本的、低延时、非连接的数据报流传输服务。 UDP的简单性使得UDP协议路由表数据、系统

36、信息、网络监控数据等不需要流控、应答、重排序的应用服务。,3.5.1 UDP基础知识,UDP报文与IP报文的关系,UDP首部,3.5.2 Linux中UDP协议分析,3.5.2.1 UDP协议功能实现,UDP的功能主要在“ipv4/udp.c”中实现,主要由创建、发送与接收三个部分函授构成。,创建UDP套接字的任务在于建立建套接字的文件操作表(socket_file_ops)与支持UDP协议的网络套接字操作表(udp_prot)之间的连接。 UDP的发送主要是由函数udp_sendmsg()完成的,这个函数被inet层的发送函数调用,最后调用ip层的发送函数把数据报发送出去。 UDP的接收主要有两个函数:udp_rcv()和udp_recvmsg()。 udp_rcv()在内核接收到一个

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论