上次内容回顾
-
网络性能衡量指标
- 带宽:通信信道上支持的最高数据传输频率
- 速率:每秒中传输多少bits数据
- 吞吞量:单位时间内通过某个网络数据量
- 时延:传输时延,传播时延,处理时延,排队时延
-
常用概念
- 服务器:提供服务的一方
- 客户端:请求服务的一方
- 通信:数据传输过程
- 协议:数据组织、编码、传输、校验、解码规则
-
通信过程的几个问题
- DNS:域名系统,获得对方IP地址
域名 ====> IP地址 - 联系上对方:客户端主动发起连接
- 通信过程的正确性:协议来保证
- 如何正确理解对方的意思:协议来保证
- 关闭连接
- DNS:域名系统,获得对方IP地址
-
OSI/ISO七层参考模型
- 应用层:提供用户服务,负责具体功能的实现
- 表示层:数据格式的压缩,优化,加密
- 会话层:建立应用的连接,选择合适的传输服务
- *传输层:提供传输服务(程序之间)
- 网路层:主机到主机间的数据传输
路由,分段 - 链路层:进行数据交换,控制具体收发
相邻主机之间的通信 - 物理层:定义机械、物理、电信标准
-
TCP/IP四层模型
- 应用层(应用层、表示层、会话层)
- 传输层(传输层)
- 网络层(网络层)
- 物理链路层(数据链路层、物理层)
- 将第一次分为两层,就是五层模型
-
IP地址:网络上唯一的地址
-
组成:32bits
-
表示方式:点分十进制的表示方式
将每8bits分成一组,使用十进制的数字表示
11111111 11111111 11111111 11111111
255.255.255.255 -
特殊IP
127.0.0.1 本机IP地址
0.0.0.0 本机上绑定的所有IP地址
网络地址 主机地址全部为0
192.168.1.5
192.168.1.0
广播地址 主机地址部分全部为1
192.168.1.5
192.168.1.255 -
私有地址:预留的一部分地址段,内网使用
A类:10.0.0.1–10.255.255.254
B类:172.16.0.1–172.31.255.254
C类:192.168.0.1–192.168.255.254
-
-
端口号(端口地址):标识不同的服务
组成:16bits整数
范围:1~65535
系统保留:1~1023 系统保留端口 -
传输层:进程到进程的数据传输
-
TCP:传输控制协议
特点:面向连接,可靠传输,流量控制
适用:数据量大,可靠性要求较高的通信
传输效率较低 -
UDP:用户报文协议
特点:无连接,不可靠传输
适用:数据量小,可靠性要求不高
传输效率较高
-
-
建立、释放连接过程
-
建立:三次握手
- 客户端发起连接请求,带上自己的序列号N
- 服务器接收连接,产生应答
N+1:期望收到你下一个包的序号N+1
K:我自己的序列号K - 客户端发送确认
K+1:期望收到你下一个包的序号是K+1
-
释放:四次挥手
- 主动方发起断开请求
- 被动方应答,表示准备断开
- 被动方发出消息,表示可以断开
- 主动方发出指令,确认断开
-
-
服务器、客户端工作流程
-
服务器:
创建套接字->绑定->监听->接收->数据传输->关闭 -
客户端:
创建套接字->连接->数据传输->关闭
-
-
网络套接字(socket)
-
什么是套接字
用于计算机网络通信的一种接口 -
套接字的类型
-
流式套接字(SOCK_STREAM)
可靠性传输、面向连接、数据无差错发送
数据是一个字节流 -
数据报套接字
不可靠、无连接的数据传输
数据是一个一个独立的数据报,每次发送都是
一个数据报
-
-
常用方法
socket() 创建套接字
bind() 绑定地址
listen() 监听
accept() 接收连接
send() 发送
recv() 接收
connect() 连接(只能用于客户端)
close() 关闭
-
今天的内容:
-
服务循环接收、客户端循环发送
将服务器的recv(), 客户端的send()放入循环中 -
网络缓冲区
- 每个socket被创建后,都会分配两个缓冲区
输入、输出缓冲区,分别用于数据收、发 - 当send函数调用时,先将数据写入缓冲区
send函数就认为发送成功,并返回
由TCP协议决定何时从缓冲区发送到对方 - 当调用recv函数接收时,从输入缓冲区读取数据
而不是直接从网络读取 - 优点:提高读写效率,协调收发速度
- 每个socket被创建后,都会分配两个缓冲区
-
粘包
-
粘包:多个数据包的数据到达接收缓冲区
后一个包的头接着上一个包尾
例如:
AAABBB (两个数据包) -
什么时候需要处理粘包
如果多个数据包数据不同的分组,需要处理
属于同一个分组,不需要处理 -
如何处理:
方式一:在数据包的头部、尾部增加特殊标记
读取数据的时候,读取两个笔记中间的部分
{2H:AAA:}{2H:BBB:}方式二:在每个数据包头增加长度信息
根据长度决定读取多少个字节数据
例如:头部采用4个字节表示长度
0003AAA0004BBBB
0003:表示该包数据部分长度为3
读取3个字节:AAA
0004:表示该包数据部分长度为4
读取4个字节:BBBB
-
-
UDP套接字 ***
1)面向无连接、不可靠传输、传输效率较高、
适用于数据量少、可靠性要求不高的数据传输2)UDP工作流程
-
服务器
创建套接字->绑定地址->收发数据->关闭- 没有listen,accept过程
-
客户端
创建套接字->发送、接收数据->关闭
3)UDP套接字的主要函数
-
创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM)
参数:AF_INET 协议族,通过IP、端口
地址进行通信
SOCK_DGRAM 套接字类型
表示用户报文套接字 -
绑定(服务器端)
sockfd.bind(address)
参数:address 绑定地址,由IP、端口构成 -
接收:recvfrom
data, addr = recvfrom(buffersize)
参数:buffersize 每次最多接收的字节数
返回值:data 接收的内容
addr 消息发送者的地址 -
发送:sendto
n = sendto(data, addr)
参数:data 要发送的数据,bytes格式
addr 接收者地址
返回值:实际发送的字节数
-
-
TCP和UDP套接字的对比
TCP UDP 流 数据报 生粘包 不会产生粘包 传输 不可靠传输 listen 不需要 ccept 端connect 客户端不需要connect cv,send recvfrom,sendto -
socket常用的属性方法
family属性:地址类型
AF_INET:发送方、接收方通过IP、端口来标识
IPV4
AF_UNIX:本地socket,发送方、接收方位于
同一台机器,地址为文件路径
AF_INET6:IPV6地址类型type:socket类型
SOCK_STREAM: 流式socket
SOCK_DGRAM: 数据报socketgetpeername(): 获取连接端的地址信息
getsockname(): 获取套接字绑定的地址fileno(): 获取套接字的文件描述符
文件描述符:操作系统内核分配的一个非负整数
每个文件描述符代表一个文件
当打开或新建一个文件
内核都会返回一个文件描述符
文件读写、网络socket数据收发、
外设操作都是通过文件描述符进行
例如:
- 标准输入:sys.stdin 0 默认键盘
- 标准输出:sys.stdout 1 默认屏幕setsockopt(level, optname, value)
功能:设置套接字的选项
不同的套接字选项代表不同的功能
参数:
level: 设置选项的类型
optname: 选项类型中的子类型
value:为选项设定的值 -
广播
1)什么是广播- 单播:一点发送、一点接收
- 多播:也称组播,一点发送,特定的多个点接收
- 广播:一点发送,该网段内容所有的节点接收
广播地址:IP地址的主机地址部分全部为1
例如:192.168.1.3,转换成二进制
二进制:11000000 10101000 00000001 00000011
|------- 网络地址 -------| |-主机-|
广播地址:把主机地址部分全部替换成1
11000000 10101000 00000001 11111111
192.168.1.255
2)Python中如何实现广播
- socket既发送也接收广播的时候
首先设置SO_BROADCAST选项为1,来支持广播通信
setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
- 发送广播,使用特殊地址broadcast
而不是标准的IP地址和主机名
-
课堂练习:
利用TCP网络套接字,实现文件的传输
思路:客户端读取文件内容,依次发送至服务器端
服务器端收到数据后,写入文件
要求:完成图片文件传输容易出错的地方总结:
- 服务器监听端口和客户端连接的端口不一致
- 读取文件时,路径有问题,建议写成绝对路径
例如:/home/tarena/jeans.jpg (绝对路径)
ls /home/tarena/jeans.jpg
如果可以查看到文件,说明路径是正确的 - 打开文件模式:
发送:rb模式打开
接收:wb模式打开 - 服务器编译有错,例如服务器程序包含非法字符
最好将那一行删除,重新写一遍 - 接收文件的路径和代码不在同一个目录下
接收成功,但在代码目录下找不到