找到一个http服务器的详解+代码:https://github.com/linw7/TKeed
第一章(常识):
OSI7层:
应用:SMTP、DNS、HTTP、FTP等均为应用层
表示:
会话:RPC(远程过程调用)
传输:TCP/UDP(port到port)
网络:IP、ICMP、ARP
数据链路:ARP(OSI中属于数据链路,TCP/IP中为4曾中的网络)
物理:
ICMP,差错控制报文,采用CRC冗余校验码(使用场景:路由)
ping,是一个软件,而不是协议,走的icmp。
封装、分用的概念:
1、封装是指数据一层层经过协议往下走,每层封各层协议的头信息。
2、分用是指信息从底向上每层取出头信息。
ARP工作原理:(任意网络层地址到mac地址):查看本机的arp cache(约保存20分钟),如果没有,发起用arp请求广播包,等待告知ip与mac,有了物理地址后,开始发出icmp echo request包。
tcpdump,查看网络包。(wireshack)
TCP/IP为四层。
socket:数据链路、网络、传输层协议在内核实现,因此os需要提供system call使得应用程序访问这些协议提供的端口。
【把应用数据从用户缓冲区复制到内核tcp/udp的缓冲区,然后发送,然后再从内核缓冲区送给用户缓冲区】
【socket是一套通用网络编程接口,不仅能访问TCP/IP协议栈,还可以访问其他网络协议】
关键字:tcp7层的协议、socket细节、arp的过程
第二章(ip协议详解):
ip向上层提供无状态、无连接、不可靠的服务。
1、无状态:所有的ip数据报是独立的,发送/传输/接收独立,没有上下文关系。优点:简单、高速
2、无连接:双方都不会长期保存彼此的关系。
3、不可靠:不保证数据的正确到达。
ipv4头部结构:
源地址、目标地址、头部校验、分片偏移、TTL生存时间等。
校验和(checksum)算法,简单的说就是头部的信息全部16位累加的反码运算,存到校验处。
IP分片,数据过大时,IP数据会分片。
经典表:
路由机制:route/netstat查看路由表。
IP转发:不是发给本机的IP的数据报由数据报转发子模块处理。
ICMP报文格式:1、校验和 2、原始ip数据报头部信息+数据信息 3、应该使用的路由器ip地址
意思是返回去,告诉某个包应该发向哪里。
关键字:ip(无状态、无连接、不可靠)、ip报有校验码、ip分片、icmp重定向、ip转发的路由过程
第三章(tcp协议详解):
tcp(超时重传、一对一,无广播和多播、可靠传输、面向字节流、拥塞控制、全双工)
【字节流与数据报流的区别,体现在比如socket编程中,write与read中read是否可以分批次获取】
共用socket,但是使用时会上锁,os中的socket做了这件事。
TCP的头部结构:
源/目标端口、序列号、确认号、标志位(ACK:在创建连接和回应创建连接时;FIN:哪边发送,哪边关闭发送数据的通道;RST:复位报文,收到表示断开重新建连接(引出RST攻击)、ACK:确认报文段,除了刚开始建立,都需要确认)、窗口大小、校验和
经典图:
netstat 查看一下路由表,
网络攻击,比如ddos只发一次,server的timeout过长那么就会耗费资源。
三次握手:
client=》server(SYN=1,seq=x,SSM(滑动窗口大小0等))
syn_sent
收到后,syn_rec
server=》client(SYN=1,ACK=1,ack=x,seq=y)
client收到后,进入establish
client=》server(ACK=1,seq=y,ack=x+1)
四次挥手:
client=》server(FIN=1,ACK=1,seq=x,ack=y)
client进入fin_wait_1,
server收到后,进入time_wait,
server=》client(ACK=1,seq=y,ack=x+1)
client收到信息后,进入半关闭状态fin_wait_2。
sever进入close_wait,server的数据没有传完,仍需等到传完后通知socket传完才通知结束
server=》client(ACK=1,FIN=1,seq=k,ack=z)//server正式关闭传输
server进入last_ack
client=》server(ACK=1,FIN=1,ack=k,)
close_wait=2MSL(MSL报文在网络中的传输时间,socket时可以调整时间,节省系统资源,apache可设置?)
(随之带来的问题,网络抖动没收到关闭,或者下一次复用同一个端口可能会出错)
tcp状态转移图:
收到信息后,进入半关闭状态
复位报文段:
1、访问不存在的端口、端口在TIME_WAIT,也会获取到。
2、终止异常。
3、半打开,比如sever挂了重启,client还处于连接,那么client发送给server时收到复位报文段。
TCP的(块数据/交互数据):
根据数据长度划分,交互要求实时,块数据要求效率(如ftp服务器,要求一定时间内传输比较多)。
带外数据(比普通数据有更高的优先级,无论buffer是否有数据,直接用独立的传输层传输)
TCP超时重传:
TCP为每个TCP报文维护一个计时器,当超过计时器时间时会被重传。
拥塞控制(1、慢启动 2、拥塞避免(滑动窗口大小扩大的算法是被控制的) 3、快速重传(3个某包未收到,直接重传)
4、快恢复(收到新数据的确认的时候,会改变滑动窗口为一个初值,此时设置一个比较高的值,就会使得恢复窗口大小迅速)
关键点:tcp(超时重传、一对一,无广播和多播、可靠传输、面向字节流(一个write对应多个read)、拥塞控制、全双工)、
3次握手/4次挥手的过程、rst标志符、socket外不需要上锁,公用buffer但buffer已被锁、time_wait、close_wait(等待2MSL)、netstat查路由表
nagle算法:任何时刻都最多只能发送一个未被确认的报文,确认到达得越快,也就发送得越快。
第四章(web服务器):
正向代理/反向代理的概念。
http请求:
get(多次访问不会改变数据)、post、put、delete、optional、head
等幂(多次连续、重复的请求和只发送一次该请求具有完全相同的效果)
optional,获取这个服务器支持的请求种类。
head,只要求返回head信息,通常用来检查资源/超链接的有效性。
请求基本信息:
User-Agent:Wget/xxx,客户端使用的程序
Host:主机名
Connection:close(处理完这个请求后做啥,还有keep-alive)
http版本:1.0、1.1、2.0
1.1,
(1)主要增加了长连接,使得在一次请求后,可以复用这次TCP,降低TCP的创建与摧毁的开销。
(2)带宽优化与网络range(请求头带上range(l,r)0),不一定需要全部返回,只需要返回一部分请求的资源,这里请求range(l,r),成功的返回状态码是206。
(3)请求需要带上hostname,一台主机(一个ip)可能会有多个hostname。
2.0,
(1)从基于文本的格式解析转成二进制解析。
(2)服务器推送,一次index.html请求,附带上很多资源的请求,减少tcp创建与关闭的开销。(重点在低延迟)
(3)每次request带上id,连接到对应的tcp连接上。
(4)header压缩,就是把头信息压缩了。
其中长连接(keep alive会发生请求阻塞,每个复用的tcp通道,必须等上一次http请求处理完,才接受下一个),
那么http2.0是通过流的方式,我理解是把请求的信息放到一个buffer中,使得server可以同时处理两个请求。
响应:
返回状态码:
200:成功。
204,成功执行,但是没有数据返回。
206,返回range部分。
301,请求的资源被永久移动。
302,请求的资源被临时移动。
401,未登录。
403,请求被拒绝,权限不够。
404,找不到处理改请求的方法。
405,用户的方法不被允许。
500,服务器错误。
502,代理服务器错误,代理服务器受到了不认识的请求。
503,服务器不可用,请求队列满了
504,代理服务器帮忙处理一个http请求的时候超时了。
关键字:http的1.0.、1.1(增加默认的keep-alive(长连接)、头部带上hostname,因为一个ip可能有多个hostname、range的使用)、2.0的差别(1、tcp的复用,记录连接的id。2、压缩header 3、文本使用二进制编码 4、服务器推送,如一次推送2个请求,两个请求的资源一次返回)、常见请求,响应。
第五章(网络编程基础api):
大端字节与小端字节的区别、以及为什么要有这两种:
(学习from:http://www.ruanyifeng.com/blog/2016/11/byte-order.html)
大端存储,高位存在低地址位。用于习惯人的阅读习惯。
但是在计算的时候,需要从地位开始计算(如加法),那么在计算器计算的时候,需要从大端字节转换成小端字节。
但是在输出的时候,程序也是傻傻只会从低地址输出,如果采用的是小端字节输出,那么就会输出67、45、23、01来表示数字1234567,这不符合习惯,所以需要把它转换成大端字节才输出。