linux-网络基础二

应用层

一端发送时构造的数据, 在另一端能够正确的进行解析, 就是ok的. 这种约定, 就是 应用层协议
负责程序之间的数据沟通

自定制协议:

结构化数据的传输
序列化:将数据对象按照指定协议组织成为可持久化存储/数据传输的二进制数据串格式
反序列化:二进制数据串按照指定的协议解析出数据对象

HTTP协议(超文本传输协议)

平时我们俗称的 “网址” 其实就是说的 URL
URL:统一资源定位符
urlencode:用户提交的数据中若由特殊字符需要进行编码操作- -每个字节转换为16进制字符串,为了表明这两个字符经过了编码操作,因此在前边加上%符号进行标识
urldecode:遇到%符号,则取出紧跟其后的两个字符,第一个字符转换为数字左移四位+第二个字符转换的数字
urldecode就是urlencode的逆过程

HTTP协议格式

HTTP请求:

  • 首行: [方法] + [url] + [版本]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度
    HTTP响应:
  • 首行: [版本号] + [状态码] + [状态码解释]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.

HTTP的方法

在这里插入图片描述

HTTP的状态码

在这里插入图片描述

HTTP常见Header

  • Content-Type: 数据类型(text/html等)
  • Content-Length: Body的长度
  • Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
  • User-Agent: 声明用户的操作系统和浏览器版本信息;
  • referer: 当前页面是从哪个页面跳转过来的;
  • location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
  • Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

简单的HTTP服务器实现:

http是应用层协议,在传输层使用tcp协议实现传输,默认使用80端口
1.搭建tcp服务端程序
2.按照http协议格式,对接收到的数据进行解析(METHOD,URL,VERSION,HEADER,BODY)
3.根据请求UPL队请求作出不同的处理
4.对客户端进行响应(首行\r\n头部\r\n\r\n正文)
这里不管客户端发送什么请求,统一响应

<html><body><h1> Hello World</h1></body></html>

传输层

负责数据能够从发送端传输接收端.

UDP协议

UDP协议字段格式

在这里插入图片描述

  • 16位UDP长度, 表示整个数据报(UDP首部+UDP数据)的最大长度
  • 如果校验和出错, 就会直接丢弃

UDP的特点

UDP传输的过程类似于寄信.

  • 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息;
  • 面向数据报: 不能够灵活的控制读写数据的次数和数量
面向数据报

应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并;
用UDP传输100个字节的数据:
如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个
字节; 而不能循环调用10次recvfrom, 每次接收10个字节;

UDP的缓冲区

UDP没有真正意义上的 发送缓冲区. 调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后
续的传输动作;
UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果
缓冲区满了, 再到达的UDP数据就会被丢弃;
UDP的socket既能读, 也能写, 这个概念叫做 全双工

UDP使用注意事项

我们注意到, UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).
然而64K在当今的互联网环境下, 是一个非常小的数字.
如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;
基于UDP的应用层协议

  • NFS: 网络文件系统
  • TFTP: 简单文件传输协议
  • DHCP: 动态主机配置协议
  • BOOTP: 启动协议(用于无盘设备启动)
  • DNS: 域名解析协议
    当然, 也包括自己写UDP程序时自定义的应用层协议

TCP协议

TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制.

TCP协议字段格式

在这里插入图片描述

  • 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;
  • 32位序号/32位确认号: 后面详细讲;
  • 4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 = 60
  • 6位标志位:
    URG: 紧急指针是否有效
    ACK: 确认号是否有效
    PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
    RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
    SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
    FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
  • 16位窗口大小: 用于实现滑动窗口机制
  • 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分.
  • 16位紧急指针: 标识哪部分数据是紧急数据;
  • 40字节头部选项:用到的时候才会有,意味着tcp头部长度不固定

TCP协议特性

面向连接,可靠传输,面向字节流

面向连接

在正常情况下, TCP要经过三次握手建立连接, 四次挥手断开连接:
在这里插入图片描述

服务器初始化:
  • 调用socket, 创建文件描述符;
  • 调用bind, 将当前的文件描述符和ip/port绑定在一起; 如果这个端口已经被其他进程占用了, 就会bind失败;
  • 调用listen, 声明当前这个文件描述符作为一个服务器的文件描述符, 为后面的accept做好准备;
  • 调用accecpt, 并阻塞, 等待客户端连接过来;
建立连接的过程(三次握手):
  • 调用socket, 创建文件描述符;
  • 调用connect, 向服务器发起连接请求;
  • connect会发出SYN段并阻塞等待服务器应答; (第一次)
  • 服务器收到客户端的SYN, 会应答一个SYN-ACK段表示"同意建立连接"; (第二次)
  • 客户端收到SYN-ACK后会从connect()返回, 同时应答一个ACK段; (第三次)
    这个建立连接的过程, 通常称为 三次握手
数据传输的过程
  • 建立连接后,TCP协议提供全双工的通信服务; 所谓全双工的意思是, 在同一条连接中, 同一时刻, 通信双方可以同时写数据; 相对的概念叫做半双工, 同一条连接在同一时刻, 只能由一方来写数据;
  • 服务器从accept()返回后立刻调用read(), 读socket就像读管道一样, 如果没有数据到达就阻塞等待;
  • 这时客户端调用write()发送请求给服务器, 服务器收到后从read()返回,对客户端的请求进行处理, 在此期间客户端调用read()阻塞等待服务器的应答;
  • 服务器调用write()将处理结果发回给客户端, 再次调用read()阻塞等待下一条请求;
  • 客户端收到后从read()返回, 发送下一条请求,如此循环下去;
断开连接的过程(四次挥手):
  • 如果客户端没有更多的请求了, 就调用close()关闭连接, 客户端会向服务器发送FIN段(第一次);
  • 此时服务器收到FIN后, 会回应一个ACK, 同时read会返回0 (第二次);
    read返回之后, 服务器就知道客户端关闭了连接, 也调用close关闭连接, 这个时候服务器会向客户端发送一个FIN; (第三次)
  • 客户端收到FIN, 再返回一个ACK给服务器; (第四次)
    这个断开连接的过程, 通常称为 四次挥手
主动关闭方,为什么没有直接关闭释放套接字,而是进入TIME_ WAIT状态,等待一段时间才关闭

假设主动关闭方直接释放套接字,但是最后一次回复的ACK丢失, 有可能会对后续连接造成影响

  1. ack丢失,被动关闭方重传FIN请求报文,主动关闭方重新启动相同地址的客户端,会收到这个报文
    2.主动关闭方,重新启动适用相同地址,发送SYN请求报文,有可能会出现状态错误
    因此主动关闭方,回复最后一次ACK之后,需要等待一段时间:
    1.处理被动关闭方有可能重传的ACK报文
    2.等待2个MSL时间,确保重传的报文消失在网络中
    MSL:报文的最大生命周期
三次握手为什么三次:

三次握手建立连接,是为了确保通信双方都具有收发数据的能力
两次不安全:状态迁移变化,确保服务端不会位迟到的重复SYN建立连接,并且服务端不能保证 客户端具有收发数据的能力
四次没必要: SYN和ACK只是两个标志位,没必要分成两个报文进行发送

四次挥手为什么四次:

因为被动关闭方,收到FIN请求报文后,立即进行ACK回复,接下来需要等待用户调用close接口进行确认,缓冲区中的数据已经处理完毕/不关心这些数据了,才会向对方发送FIN请求报文,得到ACK回复后,则直接释放socket,因此被动关闭方的ACK和FIN不能直接放在一起进行回复

tcp连接管理中保活机制:

tcp通信双方若长时间无数据往来,则每隔一段时间向对方发送保活探测数据报,要求对方进行回复;若连续多条保活请求没有响应,则认为连接断开
连接断开在程序中的体现: recv读完所有数据之后,返回0; send 触发异常SIGPIPE

握手失败如何处理:

服务端等待最后一个ACK报文超时后,向客户端恢复RST报文,然后关闭释放socket
避免SYN泛洪攻击

可靠传输
可靠传输:
  • 1.tcp面向连接
  • 2.确认应答机制
  • 3.超时重传机制
  • 4.协议字段中序号/确认序号
  • 5.协议字段中的校验和
    可靠传输牺牲了部分性能,但是有些损失是可以避免的
提高性能

提高性能:滑动窗口机制(流量控制,快速重传,拥塞控制),延迟应答机制,捎带应答机制

1.滑动窗口机制
  通信双方,在通信时会通过协议字段中的窗口字段协商窗口大小,告诉对方一次可以发送的最大数据量,
  当然这些数据不可能一条数据全部发送,通信双方通常在三次握手阶段,还会协商一个数据叫MSS (最大数据段大小-数据报中数据的最大长度),
  发送方在发送数据的时候会将窗口大小的数据分成多个大小不大于MSS大小的数据报进行发送

在这里插入图片描述

  • 1.流量控制:通过协议字段中的窗口字段,通知发送方能够发送的最大数据量,通过这个来限制对方的发送速度,避免发送过快,导致接收缓冲区塞满,而引起的后续数据丢包重传
  • 2.快速重传:当接收方接收到第二条数据,但是没有接收到第一条, 则认为第一条有可能丢失, 则立即向发送方发送第一条数据的重传请求, 并且将这个重传请求,连续发送三次;发送方连续三次接收到重传请求,则对这条数据进行重传
    连续发送三次重传请求,是为了避免有可能因为网络阻塞而接收到延迟的数据
  • 3.拥塞控制:发送方维护一个拥塞窗口, 控制-次发送的数据量,拥塞窗[以慢启动快增长的形式控制传输的数据量,起到对网络进行探测的作用,可以避免因为网络状况不好而导致的大量丢包
    在这里插入图片描述
  • 当TCP开始启动的时候, 慢启动阈值等于窗口最大值;
  • 在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1

少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力折中方案.

2.捎带应答机制:

接收方位每一条接收到的数据组织报文, 通过报文头部中的确认序号字段进行确认回复,这时候如果刚好有要给对方发送的数据,则将这次的确认回复序号直接放到要发送的这条数据头中,可以节省一条空报文的回复,提高传输效率
在这里插入图片描述

3.延迟应答机制:

接收方接收到数据之后,如果立即进行回复,窗1大小就会降低,导致传输吞吐率降低,降低了发送速度;
这时候如果收到数据之后,延迟一会进行确认回复,则有可能用户将缓冲区中的数据取走,保证传输吞吐率

面向字节流
  • send发送的数据,会先放到socket的发送缓冲区中,然后操作系统选择合适的时机将数据发送出去
  • 多条小数据融合成一个大包发送出去,可以提高一定的传输性能;
  • 并且接收方,传输层数据的交付也比较灵活,可以一点一点交付,也可以一次性全部交付所有数据
粘包问题

字节流服务会造成数据的粘包问题:多条数据在缓冲区中粘连在一起
粘包的本质原因: tcp在传输层对数据的格式边界不敏感,不会替用户区分哪条数据从哪开始,到哪结束,只关注需要向用户交付多长字节的数据
因此粘包问题的解决方案就是用户在应用层进行数据的边界管理:
1.特殊字符,2.数据定长,3.不定长数据在应用头中声明数据长度

基于TCP应用层协议

HTTP
HTTPS
SSH
Telnet
FTP
SMTP
当然, 也包括自己写TCP程序时自定义的应用层协议

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值