Linux系统编程教学设计-Linux网络基础编程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程名称: Linux高级系统编程
_______________
授课年级: ___________________________ 授课学期: ___________________________ 教师姓名: ___________________________
202X年03月01日
课程名称第8章网络基础编程计划
学时
4学时
内容分析本章主要介绍TCP编程、UDP编程、数据包解析、Wireshark工具
教学目标与
教学要求
要求学生掌握TCP、UDP编程、掌握TCP连接与断开机制、掌握TCP、UDP数据包格式、封装及拆解方法、掌握Wireshark抓包工具使用方法以及数据分析
教学重点TCP编程、UDP编程、数据包解析、Wireshark工具教学难点数据包解析、Wireshark工具
教学方式课堂讲解及ppt演示
教
学
过
程 第一课时 (TCP 编程、UDP 编程) 内容回顾 1. 回顾上节内容,引出本课时主题。
本章将开始介绍TCP 、UDP 网络基础编程。
首先介绍其使用接口,并通过代码示例展示TCP 编程、UDP 编程的基本框架与流程。
其次介绍TCP 、
UDP 的数据包格式,以及封装、拆解过程,包括TCP 建立连接以及断开的过程;最后介绍Wireshark 抓包工具的基本使用,并简单分析TCP 抓包过程,培养读者网络协议编程的能力。
从而引出本节的内容。
2. 明确学习目标
(1)能够掌握TCP 编程流程
(2)能够掌握创建套接字
(3)能够掌握TCP 服务器接口
(4)能够掌握TCP 客户端接口
(5)能够掌握TCP 编程通信实现
(6)能够掌握UDP 编程流程
(7)能够掌握发送和接收数据
(8)能够掌握UDP 编程通信实现
(9)能够掌握TCP 三次握手和四次挥手
(10)能够掌握数据包封装与解析
(11)能够掌握TCP 、UDP 、IP 封包格式
知识讲解
TCP 编程流程
TCP (传输控制协议)是TCP/IP 体系中的面向连接的传输层协议,在网络中提供全双工的、可靠的服务。
由第7章的内容可知,TCP 通信是通过套接字通信机制实现的,具体为流式套接字,用来实现一个面向连接,可靠的数据传输服务。
目前较为流行的网络编程模型是客户端、服务器的通信模式。
服务器和客户端使用TCP 通信(同时适用UDP )的流程如图所示。
套接字编程的基本函数有socket()、bind()、listen()、accept()、send()、
发送、接收数据
使用UDP编程进行通信时,发送、接收数据使用sendto()函数、recvfrom()函数来完成。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
sendto()函数用来实现数据的发送。
参数sockfd为套接字的文件描述符,参数buf用来保存发送的数据。
参数len表示发送数据的长度。
flags参数一般默认为0。
参数dest_addr指定数据接收方的网络信息结构体(IP地址、端口号)。
参数addrlen用来指定网络信息结构体的长度。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
recvfrom()函数用来接收数据。
参数sockfd表示套接字的文件描述符,参数buf用来保存接收的数据。
参数len表示数据的长度。
flags参数一般默认为0。
参数src_addr指定数据发送方的网络信息结构体(IP地址、端口号)。
参数addrlen用来指定网络信息结构体的长度。
UDP编程通信实现
下面将通过示例展示UDP通信的套接字编程,完成数据的传输。
服务器端的案例详情参考教材6.2.3节。
TCP三次握手、四次挥手
8.1节中介绍了使用TCP协议进行通信的编程流程,TCP是面向连接的,且具有可靠传输的协议。
因此在实现数据收发之前需要建立连接。
建立TCP 连接以及断开连接是一个较为复杂的过程。
当建立一个TCP连接时,需要客户端和服务器端总共发送3个包以确认连接的建立,这个过程被称为“三次握手”。
而当断开TCP连接时,需要客户端和服务器端总共发送4个包以确认连接的断开,这个过程被称为“四次挥手”。
三次握手的过程如下。
(1)服务器通常通过调用socket()、bind()和listen()这3个函数准备好接收外来的连接,称之为被动打开。
(2)客户端通过调用connect()发送主动打开。
这导致客户端发送一个同步序列编号(Synchronize Sequence Numbers,SYN)分节,以告诉服务器客户端在(待建立的)连接中发送的数据的序列号。
通常,SYN分节不携带数据。
(3)服务器通过发送ACK确认报客户端的SYN,同时自己也发送一个SYN分节,这个SYN分节含有服务器将在同一连接中发送的数据的初始序列号。
(4)客户端必须确认服务器的SYN。
这种交换至少需要3个分组,因此称之为TCP的三次握手。
TCP的三次握手过程如图所示,客户端的初始序列号为J,服务器的初始序列号为K。
TCP建立一个连接需要3个分节,终止一个连接则需要4个分节。
四次挥手的过程如下。
(1)某个应用进程首先调用close()函数,称该端执行主动关闭。
该端的TCP于是发送一个FIN分节,表示数据发送完毕。
(2)接收到这个FIN的对端执行被动关闭。
它的接收也作为一个文件结束符传递给接收端应用进程。
FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
(3)一段时间后,接收到这个文件结束符的应用进程将调用close()函数关闭它的套接字,这导致它的TCP也发送一个FIN。
(4)接收这个最终的FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
类似SYN,一个FIN也占据1个字节的序列号空间。
因此,每个FIN 的ACK确认号就是这个FIN的序列号加1。
由于TCP连接是全双工的,因
此,每个方向都必须单独进行关闭。
这一原则是当一方完成数据发送任务之后,发送一个FIN 来终止这一方向的连接,收到一个FIN 只是意味着这一方向上没有数据流动,即不会再收到数据。
但是这个TCP 连接上仍然能够发送数据,直到这一方向也发送了FIN 。
其挥手过程如图所示。
TCP 涉及连接建立和连接终止的操作可以用状态转换图来说明,如图所示。
TCP 连接定义了11种状态,并且TCP 规定如何基于当前状态及在该状态下所接收的分节从一个状态住转换为另一个状态。
例如,当某个应用进程在CLOSED 状态下执行主动打开时,TCP 将主动发送一个SYN ,且新的状态是SYN_SENT 。
如果这个TCP 接着接收到一个带ACK 的SYN ,它将发送一个ACK ,且新的状态是ESTABLISHED 。
这个最终状态是绝大多数数据传输发生的状态。
自ESTABLISHED 状态引出的两个箭头处理连接的终止。
如果某个应用进程在接收到一个FIN 之前调用close()函数(主动关闭),则状态转换为FIN_WAIT_1状态。
但如果某个应用进程在ESTABLISHED 状态期间接收到一个FIN (被动关闭),那就转换到CLOSE_WAIT 状态。
数据包封装与解析
7.1.3节中介绍了TCP/IP 体系结构,在该结构中定义了分层的思想。
一CLOSED
开始
LISTEN
被动打开
SYN 收到
SYN_SENT 应用进程:被动打开
发送:无
收:SYN
发:SYN,ACF
同时打开ESTABLISED
主动打开应用进程关闭或超时FIN_WAIT_1CLOSING
收:FIN 发:ACK CLOSE_WAIT 收:FIN
发:ACK 数据传送状态
同时关闭
FIN_WAIT_2
收:ACK 发送:无TIME_WAIT 收:FIN
发:ACK 收:ACK
发送:无
2MSL 超时LAST_ACK 收:FIN
应用进程关闭被动关闭收:ACK 发送:无说明客户的正常状态变迁
说明服务器的正常状态变迁
应用机制:说明当应用执行某种操作时发生的状态变迁
说明为了进行某个状态变迁要发送TCP 报文段
共分为四层,分别为应用层、传输层、网络层、网络接口和物理层。
其中最重要的是,每层协议都使用下层协议提供的服务,并向自己的上层提供服务。
而实现这一模式的方式叫做封装。
应用程序数据在发送到物理网络上之前,将沿着协议栈从上往下依次传递。
每层协议都将在上层数据的基础上加上自己的头部信息(有时还包括尾部信息),以实现该层的功能,这个过程就是封装。
如图所示。
如图所示,将TCP头部信息和数据合并,经过TCP封装后的数据称为TCP报文段。
经过UDP封装后的数据称为UDP数据报。
UDP对应用程序数据的封装与TCP类似。
不同的是,UDP无须为应用程序数据保存副本,因为它提供的服务是不可靠的。
经过IP封装后的数据称为IP数据报。
IP数据报包括头部信息和数据部分,其中数据部分就是一个TCP报文段或UDP数据报。
经过网络接口和物理层封装的数据称为帧。
传输媒介不同,帧的类型不同。
比如,以太网上传输的是以太网帧,而令牌环网络上传输的是令牌环帧。
数据报文经过以太网的封装后,就要通过网络或其他传输介质发送到另一端;另一端收到数据报后最先接触的是以太网层,该层协议负责把以太网首部解析掉。
然后把解析后的数据报上送IP层,IP层将IP头部解析掉,然后上传至TCP层。
以次类推,每层协议解析其头部,并判断其头部中的协议标识以确定接收数据的上层协议,然后送到上一层。
TCP、UDP、IP封包格式
正如上一节介绍,应用程序数据在发送的过程中,会对其进行层层封装。
例如,TCP/UDP头部、IP头部等,每一层的头部信息定义了该层的功能。
本节将对这些常见的头部信息进行讨论,即封包格式。
了解这封包格式将有助于读者对协议有更深刻的认识。
1. TCP报文格式
图所示为TCP报文格式,包括其中的字段含义解释如下所示。
(1)源端口号:TCP发送端的端口号。
(2)目的端口号:TCP接收端的端口号。
(3)序列号:该报文的序列号,标识从TCP发送端向TCP接收端发送的数据字节流。
避免出现接收重复包,以及可以对乱序数据包进行重排序。
(4)确认序号:标识了报文发送端期望接收的字节序列。
注意它是一个准备接收的包的序列号。
(5)头部长度。
该字段用来表示TCP报文头部的长度,头部长度单位是32位(即4字节)。
由于这个字段只占4个比特位,因此头部总长度最大可达到60字节(15个字长)。
该字段使得TCP接收端可以确定变长的选项字段的长度,以及数据域的起始点。
(6)保留位:该字段包含4个(未使用,必须置为0)。
(7)控制位:该字段由8个比特位组成,用于进一步指定报文的含义。
CWR:拥塞窗口减小标记
ECE:显式的拥塞通知回显标记。
URG:如果设置了该位,那么紧急指针字段包含的信息就是有效的。
ACK:如果设置了该位,那么确认序号字段包含的信息就是有效的(即,该字段可用来确认由对端发送过来的上一个数据)。
PSH:将所有收到的数据发给接收的进程。
RST:重置连接。
该字段用来处理多种错误情况。
SYN:同步序列号。
在建立连接时,双方需要交换该位的报文。
这样使得TCP连接的两端可以指定初始序列号,稍后用于在双向传输数据。
FIN:发送端提示已经完成了发送任务。
(8)窗口大小:该字段用在接收端发送ACK确认时提示自己可接收数据的空间大小。
(9)校验和:奇偶校验,此校验和是针对整个的TCP报文段,包括TCP头部和TCP数据。
由发送端计算,接收端进行验证。
(10)紧急指针:如果设定了URG位,那么就表示从发送端到接收端传输的数据为紧急数据。
(11)选项:这是一个变长的字段,包括了控制TCP连接操作的选项。
(12)数据:这个字段包含了该报文段中传输的用户数据。
如果报文段没有包含任何数据的话,这个字段的长度就为0。
2. UDP封包格式
图所示为UDP的封包格式,包括其中的字段含义解释如下所示。
(1)源端口号:UDP发送端的端口号。
(2)目的端口号:UDP接收端的端口号。
(3)UDP长度:UDP头部和UDP数据的字节长度。
(4)UDP校验和:UDP校验和是一个端到端的检验和。
它由发送端计算,然后由接收端验证。
其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。
3. IP数据报的格式
图所示为IP数据报的封包格式,普通的IP头部长为20个字节,除非含有选项字段。
(1)版本。
目前协议的版本号为4,因此IP有时也称为IPv4。
(2)头部长度。
头部长度指IP头部的大小,包括任何选项,其单位为32为(4字节)。
由于它是一个4位字段,因此头部最长为60个字节(4位头部长度字段所能表示的最大值为1111,转化为十进制为15,15*32/8 = 60)。
(3)服务类型。
服务类型字段包括一个3位的优先权子字段,4位的TOS子字段和1位未用位(但必须置0)。
TOS字段为4位,第1位表示最小时延,第2位表示最大吞吐量,第3位表示最高可靠性,第4位表示最小费用。
如果修改这个字段,只能选择4 位中的1 位进行操作。
如果所有4 位均为0,那么就意味着是一般服务。
(4)总长度。
总长度指整个IP数据报的长度,以字节为单位。
利用头部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。
由于该字段长16bit,所以IP数据报最长可达65535字节。
总长度字段是IP头部中必要的内容,因为一些数据链路(如以太网)需要填充一些
数据以达到最小长度。
尽管以太网的最小帧长为46字节,但是IP数据可能会更短。
如果没有总长度字段,则IP层就无法知道46字节中IP数据报的内容长度。
(5)标识:标识是指主机发送的每一份数据报。
通常每发送一份报文,其值就会加1。
(6)生存时间(TTL)。
生存时间字段设置了数据报可以经过的最多路由器数。
它指定了数据报的生存时间。
TTL的初始值由源主机设置(通常为32或64),一旦经过一个处理它的路由器,它的值就减1。
当该字段的值为0时,数据报就会被丢弃,并发送ICMP报文通知源主机。
(7)任选项:任选项是数据报中的一个可变长的可选信息。
目前,这些任选项包括安全和处理限制、记录路径、时间戳、宽松的源站选路、严格的源站选路(与宽松的源站选路类似,但是要求只能经过指定的这些地址,不能经过其他的地址)。
这些选项很少被使用,并非所有的主机和路由器都支持这些选项。
选项字段一直都是以32 位作为界限,在必要的时候插入值为0的填充字节。
这样就保证IP头部始终是32 位的整数倍(这是头部长度字段所要求的)。
第二课时
(网络基础知识)
内容回顾
1. 回顾上节内容,引出本课时主题。
上节已经介绍了TCP编程、UDP编程、数据包解析的内容,下面将介绍Wireshark工具内容。
2. 明确学习目标
(1)能够掌握Wireshark工具安装
(2)能够掌握Wireshark实现抓包
(3)能够掌握Wireshark显示封装信息
(4)能够掌握Wireshark抓包分析TCP
知识讲解
Wireshark工具安装
Wireshark 是最著名的网络通讯抓包分析工具。
其功能十分强大,可以截取各种网络封包,显示网络封包的详细信息。
Wireshark适用于许多场合下,典型的应用案例包括解决网络问题、检测安全隐患、测试诸如即时通讯软件的协议执行情况等。
因此本节将首先介绍在Linux以及Windows环境下,如何对Wireshark 抓包工具进行安装。
1. Linux系统安装Wireshark
首先在Linux(ubuntu)系统上进行安装,具体的步骤如下所示。
(1)由于系统采用的安装方式为在线安装。
因此,安装之前需要确保是否连接网络。
首先更新系统源,因为Wireshark抓包需要监控网卡等资源,所以使用root权限安装,具体案例详情参考教材8.4.1节。
(2)安装wireshark:sudo apt-get install wireshark。
如遇到询问是否继续时,选择输入“y”,表示继续(截取部分)。
(3)安装完成后,在终端使用管理员身份执行Wireshark(即终端输入sudo wireshark),然后就会出现Wireshark的图形界面了。
如果出现错误信息可以忽略,具体案例详情参考教材8.4.1节。
2. Windows系统安装Wireshark
在Windows环境下安装Wireshark工具,可以选择登录Wireshark官方网站,根据需要选择下载32位或64位版本,具体案例详情参考教材8.4.1节。
Wireshark实现抓包
1. Ubuntu系统运行Wireshark实现抓包
本次将使用在Ubuntu系统中运行的Wireshark进行数据抓包演示,并选用在8.1.5节中的TCP编程示例,展示抓包的方法。
在Ubuntu系统中安装完成Wireshak工具之后,在终端以管理员身份运行Wireshark指令,进入抓包工具界面,打开可以进行抓包的网卡列表,本次抓包由于是在一个主机的系统中进行抓包,并没有使用真实的物理网卡,因此选择虚拟网卡进行抓包。
具体案例详情参考教材8.4.2节。
2. Windows系统运行Wireshark实现抓包
前面介绍了在虚拟机运行的Ubuntu系统中,同时运行服务器和客户端进行TCP通信,并完成抓包的实验。
其抓包工具选用的是Ubuntu中运行的Wireshark。
具体案例详情参考教材8.4.2节。
Wireshark显示封装信息
在两节上已经讨论了Wireshark的安装以及使用其进行抓包演示。
本节将以一次抓包的数据为例,对抓包的数据进行解释。
以便于可以更快速地分析其他的数据包内容。
具体的分析如下。
(1)Wireshark窗口界面介绍,如图所示,是抓包后的窗口界面以及界面描述。
2)封包列表的面板上显示的内容包括编号、时间戳、源地址、目标地址、协议、长度,以及封包信息。
不同的协议会使用不同颜色。
可以自行设置在View选项中的Color Rules中修改显示颜色的规则。
(3)封包详细信息,是最重要的信息,用来查看协议中每一个字段。
OSI 七层模型分别为物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
在封包信息中,每行对应的含义及在OSI模型中的对应关系如下:Frame:物理层的数据帧概况,对应OSI七层模型中的物理层。
Ethernet II:数据链路层以太网帧头部信息,对应OSI七层模型中的数据链路层。
Internet Protocol Version 4:互联网层IP包头部信息,对应OSI七层模型中的网络层。
Transmission Control Protocol:传输层的数据段头信息,此处是TCP,对应的是OSI七层模型中的传输层。
Hypertext Transfer Protocol:应用层的信息,对应OSI七层模型中的应用层。
(4)针对上述封包详细信息,逐一进行解读,选取示例为随机选取,可能会根据数据包的不同以及抓包工具的不同,其信息显示格式略有不同。
读者可自行抓包选取进行对比查看。
数据包物理层Frame层解析,及注释如下。
具体案例详情参考教材8.4.3节。
Wireshark抓包分析TCP协议
根据在8.3.3节中介绍的协议封包格式,将封包格式中的字段信义与Wireshark捕获的TCP包中的数据参数进行对照,可以更直观地理解TCP的通信过程。
本次将使用8.1.5节中的TCP编程程序,在U buntu系统中直接运行本地客户端与服务器端进行抓包分析。
从而获得关于TCP的三次握手与四次挥手的具体情况。
图中的3条数据包是一次TCP建立连接的过程,即三次握手的情况。
第一次握手,客户端发送一个TCP,标志位(SYN)为1,序列号seq 为0(假设此seq为i,i==0),源端口号为54918,目的端口号为8080。
代表客户端请求建立连接,如图所示。
可以看出这里的Flags(12位)与TCP 封包格式头信息中的保留位(4位)和控制位(8位)一一对应。
Flags值为0x002(0000 0000 0010),其中表示SYN的位在低位第二位,因此SYN值为1。
第二次握手,服务器向客户端返回一个数据包,标志位SYN为1,建立回复确认序列号ACK设置为i+1,即为1。
同时会选选取一个序列号为0(假设为j,j==0)源端口号为8080,目的端口号为54918。
如图所示。
第三次握手,客户端接收到服务器发送的数据包后,检查其确认序列号是否正确,即i+1(为1)。
若正确,客户端会向服务器发送一个数据包,其SYN为0,确认序列号ACK为服务器端发送的序列号j+1(为1),和本次需要发送的序列号为i+1(为1)。
至此,一次TCP连接就此建立,则可以开始传输数据。
如图所示。
根据上述解析,可以清楚地看到TCP三次握手的具体信息参数。
同时在此基础上,可以更好地理解三次握手的过程及原因。
TCP客户端之所以最后要发送一次确认,通过三次握手建立连接,主要是为了防止已经失效的连接请求报文又发送到了服务器,再次建立TCP连接产生错误。
假设在这样一个场景中,客户端发送请求报文后,在网络中的某个节点滞留一段时间,TCP客户端迟迟没有收到服务器的确认报文会重新向服务器发送这条报文,经过两次握手建立连接之后,传输数据,关闭连接。
而之前滞留的请求报文到达服务器之后也会与服务器再次建立连接。
如果是三次握手,客户端就不会发出确认报文,服务器收不到确认报文,就不会建立连接,减少不必要的错误。
TCP断开连接是通过发送FIN报文来告诉对方数据已经发送完毕,可以释放连接。
其Wireshark抓包列表如图所示。
本次示例使用的是在一个Ubuntu系统,运行服务器与客户端进行通信。
因此,通信使用的地址为本地主机地址(环回地址)。
由于监听本地环回,速度太快,导致服务器收到FIN以后,调用close()函数的时候,会清除socket()函数缓存区的ACK应答,这将导致无法捕获四次挥手的情况。
因此需要在服务器收到FIN之后,休眠一点时间再调用close()函数,这可以通过Wireshark看到完整的四次挥手消息。
如上图所示。
第一次挥手,当客户端的数据发送完毕之后,会向服务器端发送一个FIN(==257)的报文,用来关闭客户端到服务器端的数据传送。
第二次挥手,服务器端收到FIN后,发送一个ACK给客户端,确认序号为FIN(==257)+1。
服务器端进入关闭等待状态。
第三次挥手,服务器端发送一个FIN(==129),用来关闭服务器端到客户端的数据传送。
第四次挥手,客户端收到FIN之后,接着发送一个ACK给服务器端,确认序列号为收到序列号(==129)+1,此时服务器进入关闭状态,完成四
次挥手。
TCP断开连接之所以采用四次挥手,则是因为服务器端在监听状态下,收到连接请求SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,当收到对方的FIN报文之后,仅仅表示对方不再发送数据了
但是还能接收数据。
此时己方也有可能没有将全部数据发送给对方,因此己
方可以发送完剩余数据之后,再发送FIN报文给对方表示同意关闭连接。
因
此,己方ACK和FIN一般都会分开发送。
第三课时
上机练习(总结、练习题)
1. 总结本章内容。
2. 通过题库发送相关测试题,检查学生掌握情况。
上机练习主要针对本章中需要重点掌握的知识点,以及在程序中容易出错的内容进行练习,通过上机练习可以考察同学对知识点的掌握情况,对代
码的熟练程度。
第四课时
上机练习(总结、练习题)
1. 总结本章内容
2. 通过题库发送相关测试题,检查学生掌握情况。
上机练习主要针对本章中需要重点掌握的知识点,以及在程序中容易出错的内容进行练习,通过上机练习可以考察同学对知识点的掌握情况,对代
码的熟练程度。
习题教材第8章习题
教
学
后
记。