Linux — 网络基础二

应用层

负责应用程序之间的数据沟通
网络通信协议: 网络数据传输中的数据格式规定

自定义协议

序列化: 将数据对象按照持久化存储或者网络数据传输的格式来排布。
反序列化: 对持久化存储或者传输的数据以指定的协议进行解析的过程。

知名协议

HTTP ——超文本传输协议

URL —— 统一资源定位符(网址)

在这里插入图片描述

URL编码
因为URL中特殊字符都具有特殊含义,因此查询字符串中有特殊字符时,会造成二义性,因此需要对用户提交的数据进行编码。

编码规则:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%(进行标识),编码成%XY格式。

URL解码
在查询字符串中每遇到%,则表示之后的两个字符需要进行URL解码。

HTTP协议格式

HTTP请求

在这里插入图片描述
首行: [方法] + [URL] + [版本]
Header: 请求的属性,冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束。
Body: 空行后面的内容都是Body, Body允许为空字符串。如果Body存在,则在Header中会有一个 Content-Length属性来标识Body的长度。

在这里插入图片描述
GET所提交的数据在URL中(有长度的限制),POST所提交的数据在正文中。

HTTP响应

在这里插入图片描述
首行: [版本号] + [状态码] + [状态码解释]
Header: 请求的属性,,冒号分割的键值对,每组属性之间使用\n分隔,遇到空行表示Header部分结束。
一些重要头部: Content-Length、Content-Type、Cookie、Set_Cookie、Transfer-Encoding、Location
Body: 空行后面的内容都是Body,Body允许为空字符串。如果Body存在,则在Header中会有一个 Content-Length属性来标识Body的长度。如果服务器返回了一个html页面,那么html页面内容就是在body中。

在这里插入图片描述

传输层

负责数据能够从发送端传输接收端(进程与进程之间)

端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序(进程),在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”,“目的端口号”,“协议号” 这样一个五元组来标识一个通信(可以通过 netstat -n查看)。操作系统拿到网卡接受的数据之后,通过数据中的端口号知道数据被存放到哪一个socket的缓冲区中

查看知名端口号 cat /etc/services

传输层的传输协议

UDP

UDP协议包含字段

源端口/目的端口: 传输,确定数据应该那个端口处理
校验和: 二进制的反码求和
数据包长度: uint_16类型

  • 意味着UDP数据报最大的长度是64k,若sendto给予的数据大于64k-8(前面的信息长度为8)则会报错,因为UDP在传输层不会进行数据分段。
  • 若传输的数据大于64k,则用户需要在应用层将数据分割成一个一个小段进行传输。
  • UDP传输并不保证数据包的有序到达,因此也需要用户在应用层进行包序管理,所以UDP要求数据整条接受,否则造成数据出错。
  • UDP提供整条数据向应用层交付(也不会出现半个数据,因为头部中有报文长度标识),也正因为数据报长度在协议头中有标识,因此UDP不会产生粘报问题。

UDP协议端格式
在这里插入图片描述

UDP的特点

无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接。
不可靠: 没有确认机制, 没有重传机制;如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息。
面向数据报: 数据整条收发,灵活性低,但是不会造成粘包问题;不能够灵活的控制读写数据的次数和数量。
UDP传输速度快,实现了传输层广播数据包。

UDP的缓冲区
  1. UDP没有真正意义上的发送缓冲区(不会使用缓冲区,接受到数据后都会直接封装,然后直接交给网络层)。调用sendtod会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
  2. UDP具有接收缓冲区.,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃。

TCP协议

TCP的特点

可靠传输

提高性能: 滑动窗口机制、延迟应答机制、捎带应答机制
因为tcp为了实现可靠性传输牺牲了部分传输性能,并且有可能因为ACK确认应答丢失也要重传数据,因此提出了以下几种机制来避免大量丢包重传以及ACK丢失重传来保证性能不再降低。

滑动窗口机制

流量控制+快速重传机制+拥塞控制

流量控制

  1. tcp通过双方协商窗口大小进行流量控制,避免因为缓冲区数据塞满而大量丢包重传。
  2. 通过协议字段中的窗口大小,双方进行协商,一次可以能最多传输多少条数据,之后等待确认应答,不需要进行一一停留。
  3. 双方都维护一个窗口大小,发送方先框住一部分数据,接受到确认应答后,框开始向后移动发送数据,对方同样在窗口中使用框滑动的方式接受。

快速重传机制

  1. 每条数据的确认回复都必须按序回复,若前面的数据没有收到,则不会对后边的数据进行回复。意味着若收到一条回复,表示ACK确认序号之前的数据全部安全到达,不会因为前边的数据的ACK丢失而重传数据。
  2. 若前边的数据丢失,则接受方收到后发的数据立即发送重传请求,并且连发三次,若发送方连续收到三次重传请求,则认为数据丢失,进行重传。
  3. tcp对相同的数据包会丢弃,这样就算前面的数据因为延迟到达或者丢包,都不会对重传请求造成影响,因为无论是延迟到达还是重新发送的数据报到达,都可以减少等待确认前面数据丢包的时间。
  4. 如果数据次序发生错误,当前面的数据未收到,收到后面的数据,先将收到的后面的数据放入缓冲区,等待前面的数据到达后,再将缓冲区的数据取出。

拥塞控制
慢启动,快增长

  1. 双方虽然窗口可能很大,但是发送的数据并不大(因为刚开始时不知道网络状态),发送数据成功后,之后发送的数据按指数的增长形式,直到达到阈值,则不再增长。
  2. 发送端控制一个拥塞窗口,再进行数据传输时进行网络探测式的发送,若网络状态良好时发送的数据快速增长,达到阈值,则不再继续增长。若传输过程中出现丢包,则重新初始化拥塞窗口。
  3. 拥塞控制为了避免网络状态因为网络状态不好导致通信初始,大量数据包丢失导致重传的情况,降低性能。
延迟应答机制

接收方收到数据后并不立即确认回复,而是等待一段时间,因为这段延迟的时间内,有可能用户已经recv将缓冲区中的数据取走,窗口就可以尽可能的保证最大大小,保证传输吞吐量。

捎带应答机制

接收方对每一条数据的确认回复,都需要发送一个tcp数据报,但空包头的传输会降低性能,因此会在即将要发送的数据包头中包含确认信息(可以少发一个确认的空包头)。

面向字节流

传输灵活

  1. 发送方每次调用send都会将数据放到发送缓冲区中,然后内核选择合适的时机发送数据。
  2. 接收方网卡接受到数据,都会将数据放到接受缓冲区中,用户recv就是从接受缓冲区取数据。

粘报问题主要发生的位置

  1. 发送缓冲区中的数据堆积
  2. 接受缓冲区中的数据堆积

粘包本质原因: 数据之间没有明显的边界,tcp只管传输数据的字节流导致发送端/接受端因为数据的堆积在实际发送或recv时一次获取到半条或多条数据。
解决办法: tcp在传输层没有数据边界,但是用户可以在应用层进行边界处理
常见方法: 特殊字符间隔(HTTP),定长数据(UDP头中包含长度)

TCP协议段格式

在这里插入图片描述

TCP异常

发送端机器掉电/网线断开,接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了, 就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在。如果对方不在,也会把连接释放。
另外,应用层的某些协议,也有一些这样的检测机制。例如HTTP长连接中,也会定期检测对方的状态。断线之后,也会定期尝试重新连接。
tcp协议栈有自身的保活机制: 长时间无数据通信,则发送保活探测包,进行链接探测,若多个探测包都没有响应,则认为断开链接。
链接断开的体现: recv返回0,send出发SIGPIPE异常。

注: 具体的TCP/UDP使用可参见博客《Linux — 网络套接字编程》
https://blog.csdn.net/lw13572259173/article/details/93165915

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章