python 网络编程基础

君自故乡来,应知故乡事 / 2023-07-03 / 原文

一、软件开发架构

1、B / S :

browser 浏览器 --------〉 server

2、C / S:

client 客户端  --------〉 server

二、OSI 七层协议

1、OSI的七层协议

  1. 物理层(Physical Layer):物理层负责传输比特流(0和1)的物理介质,例如电缆、光纤和无线电频谱。它处理与物理设备之间的电压、电流和光强度等相关的细节。

  2. 数据链路层(Data Link Layer):数据存在形式为帧,数据链路层提供了一个可靠的点对点数据传输的通道,通过帧的方式将数据分成更小的单元进行传输。它还负责错误检测、纠正和流控制,以确保数据在物理介质上的正确传输。

  3. 网络层(Network Layer):数据存在形式为包,网络层负责将数据包从源主机传输到目标主机,处理分组的路由和转发。它使用IP(Internet Protocol)地址来确定数据包的目标位置,并在不同的网络之间进行跨网络的路由选择。

  4. 传输层(Transport Layer):数据存在形式为段,传输层提供端到端的数据传输服务,确保数据在源和目标之间可靠、顺序地传输。它处理数据的分段、重组、流量控制和错误恢复,同时提供不同的传输协议(如TCP和UDP)供应用程序使用。

  5. 会话层(Session Layer):会话层管理应用程序之间的通信会话,建立、维护和终止会话连接。它负责会话的同步、对话控制以及数据的检查点和恢复。

  6. 表示层(Presentation Layer):表示层处理数据的格式转换、加密和解密,以确保不同系统上的应用程序能够正确解释数据。它处理数据的压缩、编码和加密,以及数据格式的转换。

  7. 应用层(Application Layer):应用层是最高级别的层次,它提供了用户与网络服务之间的接口。应用层包括各种网络应用程序,如电子邮件、文件传输协议(FTP)、域名系统(DNS)等。

这些层次按照从底层到顶层的顺序,共同构成了OSI模型,提供了一个结构化的框架来描述和理解计算机网络通信的不同方面。值得注意的是,实际的网络协议栈可能会结合多个层次的功能,合并成更少的层次,如TCP/IP模型将物理层和数据链路层合并为网络接口层。

2、数据链路层:

该层中的数据称之为是一个数据帧,数据帧有两部分组成:head(报头)+data(真实数据)
head部分:固定18个字节
○ 发送者/源地址,6个字节
○ 接收者/目标地址,6个字节
○ 数据类型,6个字节
data:
最短46字节
# 数据报的具体内容:head长度+data长度=最短64字节

该层使用的是以太网协议,以太网协议规定,任何接入互联网的计算机都应该有一个网卡,默认的就叫以太网
Mac地址:每一个网卡都要有一个Mac地址,每块网卡出厂时都被烧制上一个世界唯一的Mac地址,长度为48位2进制,通常由12位16进制数表示
# Mac地址可以确定局域网中唯一一台计算机

三、TCP协议和UDP协议

1、TCP协议

TCP协议也叫可靠协议,流式协议(数据是可以分多次发送的)

2、三次握手

SYN、ACK、seq的含义:

  1. SYN(Synchronize):SYN是TCP协议中的一个标志位,用于建立连接的初始化阶段。当一个主机(客户端)想要与另一个主机(服务器)建立TCP连接时,它会发送一个带有SYN标志的数据包,表明它想要发起一个连接请求。

  2. seq(Sequence Number):seq是TCP协议中的一个字段,用于对数据包进行排序和重组。在TCP通信中,每个数据包都会携带一个序列号(seq number),用于标识发送方发送的数据字节的顺序。接收方使用这些序列号来正确地重组数据包,并按正确的顺序交付给应用程序。

  3. ACK(Acknowledgment):ACK是TCP协议中的一个标志位,用于确认数据包的接收情况。在TCP三次握手的过程中,除了发送SYN标志的数据包之外,还需要使用ACK标志的数据包来确认对方的数据包接收情况。例如,在服务器接收到客户端的SYN数据包后,它会发送一个带有SYN和ACK标志的数据包给客户端,表示服务器接收到了客户端的连接请求,并愿意接受连接。

综上所述,在TCP三次握手过程中,客户端首先发送一个带有SYN标志的数据包给服务器,服务器接收到后会回应一个带有SYN和ACK标志的数据包,最后客户端发送一个带有ACK标志的数据包进行确认。通过这样的交互,建立了双方之间的TCP连接。seq字段用于排序和重组数据包,确保数据的正确传输。ACK字段用于确认数据包的接收情况。

 

TCP头部通常由以下字段组成(按顺序):

  1. 源端口号(Source Port):表示发送方的应用程序使用的端口号。

  2. 目标端口号(Destination Port):表示接收方的应用程序期望接收的端口号。

  3. 序列号(Sequence Number):用于对TCP数据流进行排序和重组,表示数据流中第一个字节的序列号。

  4. 确认号(Acknowledgment Number):表示期望接收的下一个字节的序列号,用于确认已接收的数据。

  5. 数据偏移(Data Offset):指示TCP头部的长度,以4字节为单位。

  6. 保留(Reserved):保留字段,暂时未使用。

  7. 控制位(Control Bits):包括以下标志位:

    • URG(Urgent):指示紧急指针字段是否有效。
    • ACK(Acknowledgment):表示确认号字段是否有效。
    • PSH(Push):表示接收方应尽快将数据交给应用程序,而不是等待缓冲区填满。
    • RST(Reset):表示重置连接。
    • SYN(Synchronize):用于建立连接。
    • FIN(Finish):用于关闭连接。
  8. 窗口大小(Window Size):表示发送方可以接收的字节数量,用于流量控制。

  9. 校验和(Checksum):用于检测TCP头部和数据的传输错误。

  10. 紧急指针(Urgent Pointer):仅当URG标志位设置时,表示紧急数据的结束位置。

  11. 选项(Options):可选字段,用于提供额外的控制和功能。

  12. 填充(Padding):用于对齐TCP头部的长度。

数据部分(Payload)包含应用程序传输的实际数据。

通过这些字段,TCP协议可以提供可靠的、面向连接的数据传输服务,并在数据通信过程中实现序列号、确认机制、流量控制等功能。

3、使用tcpdump观察三次握手的过程

 tcpdump  -i  <interface>   'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'

在给定的tcpdump命令中,tcp[tcpflags] & (tcp-syn|tcp-ack) != 0是过滤表达式的一部分,用于筛选具有特定TCP标志的数据包。

让我们逐个解释这个过滤表达式的含义:

  • tcp[tcpflags]表示TCP头部的标志字段。它将检查每个TCP数据包的标志位。

  • &是位操作符,表示进行位与操作。

  • (tcp-syn|tcp-ack)是一个组合条件,使用位或操作符 | 将两个TCP标志 tcp-syntcp-ack 结合起来。tcp-syn 表示SYN标志位,tcp-ack 表示ACK标志位。

  • != 0表示不等于零。这个条件确保与组合条件进行位与操作后的结果不为零,即数据包的标志字段中同时设置了 SYN 和 ACK 标志位。

综上所述,tcp[tcpflags] & (tcp-syn|tcp-ack) != 0的过滤表达式会筛选出具有同时设置了 SYN 和 ACK 标志位的TCP数据包,这通常是在TCP三次握手过程中建立连接时使用的数据包。

或者:

# 在本机启动nginx服务,curl 本机
tcpdump  -i lo port  80 
root@debian:~# tcpdump -i lo port 80 -S #-S 将tcp的序列号以绝对值形式输出,而不是相对值。 
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# 第一条数据包
16:16:44.426638 IP6 localhost.54654 > localhost.http: Flags [S], seq 2442014618, win 65476, options [mss 65476,sackOK,TS val 2910674353 ecr 0,nop,wscale 7], length 0

# 第二条数据包
16:16:44.426684 IP6 localhost.http > localhost.54654: Flags [S.], seq 1828937919, ack 2442014619, win 65464, options [mss 65476,sackOK,TS val 2910674354 ecr 2910674353,nop,wscale 7], length 0

# 第三条数据包
16:16:44.426728 IP6 localhost.54654 > localhost.http: Flags [.], ack 1828937920, win 512, options [nop,nop,TS val 2910674354 ecr 2910674354], length 0

# 第四条数据包
16:16:44.426842 IP6 localhost.54654 > localhost.http: Flags [P.], seq 2442014619:2442014692, ack 1828937920, win 512, options [nop,nop,TS val 2910674354 ecr 2910674354], length 73: HTTP: GET / HTTP/1.1

# 第五条数据包
16:16:44.426852 IP6 localhost.http > localhost.54654: Flags [.], ack 2442014692, win 511, options [nop,nop,TS val 2910674354 ecr 2910674354], length 0

# 第六条数据包
16:16:44.427294 IP6 localhost.http > localhost.54654: Flags [P.], seq 1828937920:1828938770, ack 2442014692, win 512, options [nop,nop,TS val 2910674354 ecr 2910674354], length 850: HTTP: HTTP/1.1 200 OK

# 第七条数据包
16:16:44.427316 IP6 localhost.54654 > localhost.http: Flags [.], ack 1828938770, win 506, options [nop,nop,TS val 2910674354 ecr 2910674354], length 0

# 第八条数据包
16:16:44.429676 IP6 localhost.54654 > localhost.http: Flags [F.], seq 2442014692, ack 1828938770, win 512, options [nop,nop,TS val 2910674357 ecr 2910674354], length 0

# 第九条数据包
16:16:44.430228 IP6 localhost.http > localhost.54654: Flags [F.], seq 1828938770, ack 2442014693, win 512, options [nop,nop,TS val 2910674357 ecr 2910674357], length 0

# 第十条数据包
16:16:44.430251 IP6 localhost.54654 > localhost.http: Flags [.], ack 1828938771, win 512, options [nop,nop,TS val 2910674357 ecr 2910674357], length 0

分析:

三次握手(Three-way handshake):

  1. 第一条数据包:客户端向服务器发送SYN(Synchronize Sequence Numbers)报文,请求建立连接。这里,客户端选择了一个初始的序列号(seq 2442014618),并设置窗口大小(win 65476)以及其他选项。
  2. 第二条数据包:服务器收到SYN报文后,回复一个SYN-ACK(Synchronize-Acknowledge)报文。服务器也选择了一个初始的序列号(seq 1828937919),并确认客户端的序列号,即 seq+1(ack 2442014619)。服务器还设置了窗口大小(win 65464)和其他选项。
  3. 第三条数据包:客户端收到SYN-ACK报文后,发送一个ACK(Acknowledge)报文。客户端确认服务器的序列号(ack 1828937920),上一次的seq+1,并设置窗口大小(win 512)以及其他选项。至此,三次握手过程完成,连接建立。

四次挥手(Four-way handshake):⚠️:实验效果没出来,第8和9之间还缺少一次服务端同意客户端的请求

  1. 第八条数据包:在数据传输完成后,客户端发送一个FIN(Finish)报文,表示关闭连接。客户端的序列号(seq 2442014692)不变。
  2. 第九条数据包:服务器收到FIN报文后,回复一个ACK报文,确认客户端的序列号(ack 2442014693)。服务器的序列号(seq 1828938770)不变。然后,服务器发送一个FIN报文,表示同意关闭连接。
  3. 第十条数据包:客户端收到服务器的FIN报文后,回复一个ACK报文。客户端确认服务器的序列号(ack 1828938771),并设置窗口大小(win 512)以及其他选项。至此,四次挥手过程完成,连接关闭。

4、四次挥手

5、arp协议(根据IP地址计算出来Mac地址)在数据链路层

  ARP(Address Resolution Protocol)是一种网络协议,用于将网络层的IP地址解析成物理层的MAC地址。它在局域网中起到了IP地址到MAC地址的映射作用,以便在数据链路层上正确地传输数据。

当一台主机需要与另一台主机通信时,它首先会检查自己的ARP缓存(ARP Cache)中是否已经有了目标主机的MAC地址。如果缓存中存在对应的记录,则直接使用该MAC地址进行通信。如果缓存中没有对应记录,则发送一个ARP请求广播包(ARP Request

Broadcast),该包中包含目标主机的IP地址,询问局域网上的其他主机:“谁知道这个IP地址对应的MAC地址?”局域网上的其他主机收到该请求后,会检查自己的ARP缓存,如果有匹配的记录,就直接发送一个ARP响应包(ARP Reply)回复请求主机,包含自己的

MAC地址。请求主机收到响应包后,将目标主机的IP地址和MAC地址添加到自己的ARP缓存中,并使用该MAC地址进行通信。

ARP协议在局域网中起到了重要的作用,它使得主机能够通过IP地址找到目标主机的MAC地址,实现数据包在局域网内的正确传输。

 

6、TCP协议的三次握手为什么可以保证数据安全?是因为建立了双向通道吗?

原因是:TCP协议的反馈机制