七层协议
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
五层协议
应用层:FTP、HTTP、SMTP
传输层:TCP、UDP
网络层:IP
数据链路层:ARP
物理层
ARP协议
地址解析协议(Address Resolution Protocol),其基本功能为透过目标设备的IP地址,查询目标的MAC地址,以保证通信的顺利进行。它是IPv4网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代。
TCP头部
- 16位源端口号
- 16位靶端口号
- 32位序号seq,用来解决网络包乱序的问题
- 32位确认号ack,用来解决不丢包的问题
- 4位头部长度,标识多少个32bit(4Byte),4位最多表示15,所以TCP头部最长60Byte
- 6位标志位
- URG,紧急指针是否有效
- ACK,确认报文
- PSH,提示接收端立即从缓冲区读走数据
- RST,要求对方重新建立连接
- SYN,请求建立一个连接,同步报文段
- FIN,通知关闭连接
- 16位窗口大小,本端的接收缓冲区还能容纳的大小
- 16位校验和,CRC算法校验
- 16位紧急指针,紧急偏移量,是发送端向接收端发送紧急数据的方法
TCP包没有IP地址,四元组(src_ip, src_port, dst_ip, dst_port)表示一个连接。
三次握手和四次挥手
TCP状态流转图
TCP超时重传
TCP每发送一个报文段,就会对这个报文段设置一个计时器,只要计时器的重传时间得到了,但还没有收到确认,就要重传这一报文段。
1 | telnet ip port |
重传超时时间RTO
传输往返时间RTT
RTO的值
自适应算法以适应互联网分组传输时延的变化平滑计算SRTT
加权移动平均,SRTT = a SRTT + (1-a) RTT,
RTO = min[ UBOUND, max[ LBOUND, (b * SRTT) ] ]
UBOUND是最大的timeout时间,LBOUND是最小的timeout时间Karn算法
重传翻倍
TCP滑动窗口
作用:
- 可靠性
- 流量控制特性
- 面向字节流特性、
TCP标准窗口为:216-1=65535个字节
发送端的数据分成四类:
- 已经发送并收到确认
- 已经发送并未收到确认
- 允许发送并未发送
- 不允许发送
发送窗口由2和3组成
接收端的数据分成三类:
- 已接收
- 未接收准备接收
- 未接收并未准备接收
接收窗口由2组成
各自的接收窗口取决于应用、系统、硬件的限制(TCP传输效率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于对端通告的接收窗口,相同。
TCP拥塞控制
发送方维持拥塞窗口cwnd的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外,考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
慢开始
不要一开始就发送大量的数据,先探测一下网络的拥塞程度,由小到大逐渐增加拥塞窗口的大小。每收到一个报文段确认,就增加至多一个最大报文段MSS的数值,即翻倍。设置慢开始门限ssthresh,小于用慢开始,大于用拥塞避免。拥塞避免
超过ssthresh,每经过一个往返时间RTT,拥塞窗口cwnd+1快重传
接收端收到失序的报文段,发送重复确认。发送端收到3个重复确认,立即重传对方尚未收到的报文段。快恢复
发送方收到3个重复确认,乘法减小,把ssthresh门限减半,再将cwnd设置为ssthresh的大小,再执行拥塞避免算法,加法增大。
如何区分流量控制和拥塞控制?
流量控制属于通信双方协商;拥塞控制涉及通信链路全局。
流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的TCP报文段中窗口值确定;拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整。
实际最终发送窗口 = min{流控发送窗口,拥塞窗口}。
socket
服务器 | |
---|---|
socket() 创建socket | 客户端 |
bind() 绑定socket和端口号 | socket() 创建socket |
listen() 监听端口号 | connect() 连接指定计算机的端口 |
accept() 接收来自客户端的连接请求 | send()/write() 向socket中写入信息 |
recv()/read() 从socket中读取字符 | close() 关闭socket |
close() 关闭socket |
网络字节序与主机序
- 小端
低放低,高放高 - 大端
低放高,高放低
Java固定用大端。
封包和解包
Nagle算法,将多个小段数据积压,一次性发送出去。
很容易发生粘包。
解决办法:
先封包再拆包
封包:加上包头,根据包头一直接收数据,直到收够为止。
select、poll和epoll
select、poll和epoll都是多路IO复用的机制。多路IO复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行响应的读写操作。但select、poll和epoll本质上都是同步IO,因为它们都需要在读写事件就绪后自己负责进行读写,即是堵塞的,而异步IO则无须自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
- poll()比select()高级
- poll()不要求开发者在计算最大文件描述符时进行+1的操作
- poll()在应付大数目的文件描述符的时候速度更快,因为对于select()来说内核需要检查大量描述符对应的fd_set中的每一个bit位,比较费时
- select()可以监控的文件描述符数目是固定的,相对来说也较少(1024或2048)。对于poll()函数来说,就可以创建特定大小的数组来保存监控的描述符,而且poll()可以监控的文件数目远大于select()
- 对于select()来说,所监控的fd_set在select()返回之后会发生变化,所以在下一次进入select()之前都需要重新初始化监控的fd_set,poll()函数将监控的输入和输出事件分开,允许被监控的文件数组被复用而不需要重新初始化
- select()函数的超时参数在返回时也是未定义的,考虑到可移植性,每次在超时之后在下一次进入到select()之前都需要重新设置超时参数
- select()的优点
- select()的可移植性更好,在某些UNIX系统上不支持poll()
- select()对于超时值提供了更好的精度,而poll()是精度较差
- epoll()的优点
- 支持一个进程打开大数目的socket描述符(FD)
- IO效率不随FD数目增加而线性下降
- 使用mmap加速内核与用户空间的消息传递
HTTP和HTTPS
HTTP端口80,HTTPS端口443
HTTP请求方法
GET: 请求指定的页面信息,并返回实体主体。
HEAD: 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT: 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE: 请求服务器删除指定的页面。
CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS: 允许客户端查看服务器的性能。
TRACE: 回显服务器收到的请求,主要用于测试或诊断。
HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。(注意是副作用)
GET有,POST没有
HTTP状态码
状态码 | 定义 |
---|---|
1xx 报告 | 接收到请求,继续进程 |
2xx 成功 | 步骤成功接收,被理解,并被接受 |
3xx 重定向 | 为了完成请求,必须采取进一步措施 |
4xx 客户端出错 | 请求包括错的顺序或不能完成 |
5xx 服务器出错 | 服务器无法完成显然有效的请求 |
- 200:成功。
- 301:内容已经移动。
- 400:请求不能被服务器理解。
- 403:无权访问该文件。
- 404:不能找到请求文件。
- 405:所针对的资源不支持对应的请求方法。
- 500:服务器内部错误。
- 501:服务器不支持请求的方法。
- 505:服务器不支持请求的版本。
Cookie和Session
Cookie | Session | |
---|---|---|
储存位置 | 客户端 | 服务器端 |
目的 | 跟踪会话,也可以保存用户偏好设置或者保存用户名密码等 | 跟踪会话 |
安全性 | 不安全 | 安全 |
session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。
CGI、FCGI和WSGI
CGI是通用网关接口,是连接web服务器和应用程序的接口,用户通过CGI来获取动态数据或文件等。 CGI程序是一个独立的程序,它可以用几乎所有语言来写,包括perl,c,lua,python等等。
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。
WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的一种接口,WSGI的其中一个目的就是让用户可以用统一的语言(Python)编写前后端。
apache和nginx的区别
- nginx 相对 apache 的优点:
- 轻量级,同样起web 服务,比apache 占用更少的内存及资源
- 抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
- 配置简洁
- 高度模块化的设计,编写模块相对简单
- 社区活跃
- apache 相对nginx 的优点:
- rewrite ,比nginx 的rewrite 强大
- 模块超多,基本想到的都可以找到
- 少bug ,nginx 的bug 相对较多
- 超稳定