(1)滑动窗口:TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区能够用于接收数据html
滑动窗口存在于数据链路层(针对于帧的传送)和传输层(针对字节数据的传送),二者有不一样的协议,但基本原理是相近的。linux
滑动窗口指出接收缓冲区中的可用空间,从而确保发送方发送的数据不会溢出缓冲区。算法
窗口时刻动态变化:当接收发送发数据时,窗口大小减少;当接收方从缓冲区中读取数据时,窗口大小增大。编程
TCP的接收缓冲区满,它必须等待应用程序从这个缓冲区读取数据后才能再接收发送方传来的数据。segmentfault
UDP不提供流控制,按发送方的速率发送数据,无论接收方的缓冲区是否装得下。数组
## 参考文献:《UNIX网络编程》浏览器
(2)TCP拥塞的缘由:在早期的时候,通讯的双方不知道网络的情况,因此过程当中可能会出现中间节点阻塞丢包,因此就有了滑动窗口机制来解决这个问题。缓存
(3)滑动窗口协议:用于网络数据传输时的流量控制,以免拥塞的发生。若是过多的发送方同时以很快的速度发送大量的数据包,接收方有可能并无那么高的接收数据能力,所以极易致使网络的拥塞(并发服务器)。安全
协议中规定,对于窗口内未经确认的分组(传输中接收方必须确认收到的数据包。)须要重传。这种分组的数量最多能够等于发送窗口的大小。服务器
(4)滑动窗口的值:网络中没有出现拥塞,滑动窗口的值能够增大一些(以便把更多的数据包发送出去);网络出现拥塞,滑动窗口的值应该减少一些(以减小注入到网络中的数据包数)
(5)拥塞控制算法:
## 参考文章:浅谈TCP拥塞控制算法
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);- flags:
+ 0:默认设置,此时recv是阻塞接收的,0是常设置的值。
+ MSG_DONTWAIT:非阻塞接收
+ MSG_OOB:接收的是带外数据
+ ...:其它选项
(1)阻塞IO:使用recv的默认参数一直等数据直到拷贝到用户空间,这段时间内进程始终阻塞。
A从宿舍(用户空间)拿着水瓶去饮水机处(内核空间)打水,等到水打满了以后就离开了。若饮水机没有水则一直阻塞等待杯子装满水为止,才离开去作别的事情。(这种IO模型是阻塞+同步的)
(2)非阻塞IO:
改变flags,recv无论有没有获取到数据都返回(若是没有数据那么一段时间后再调用recv看看,如此循环)
B也从宿舍(用户空间)拿着水瓶去饮水机处(内核空间)打水,打开水龙头发现没有水以后离开了(回到用户空间)。
只有是检查无数据的时候是非阻塞的,在数据到达的时候依然要等待复制数据到用户空间(等着水将水杯装满)(这种IO模型是非阻塞+同步的)
(3)同步IO:IO多路复用(select, poll, epoll模型),监听多个IO对象,对象有变化(有数据)的时候就通知用户进程(单个进程能够处理多个socket)
select/epoll的优点并非对于单个链接能处理得更快,而是在于能处理更多的链接。
(4)异步IO:当进程发起IO 操做以后,就直接返回不再理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程当中,进程彻底没有被block。
## 参考文章:简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别 (以为他写的例子特别好,拿来分享)
(1)全双工:通讯容许数据在两个方向上同时传输,它在能力上至关于两个单工通讯方式的结合。能够同时进行信号的双向传输,A→B和B→A,是瞬时同步的。
(2)TCP链接:要客户端->服务器和服务器->客户端都要创建链接
(3)由于TCP的链接是全双工的,应用程序在任什么时候刻既能够发送数据也能够接收数据。TCP
为了实现可靠数据传输, TCP 协议的通讯双方都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。
三次握手的过程便是通讯双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
若是只是两次握手, 至多只有链接发起方的起始序列号能被确认, 另外一方选择的序列号则得不到确认
## 参考文章:https://blog.csdn.net/lengxiao1993/article/details/82771768
(1)三次握手同上
TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,可是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端->服务器:seq=u;服务器收到谁的FIN,发送ack=u+1;
服务器->客户端:seq=v / seq = w;客户端收到谁的FIN,发送ack=w+1,再发送本身的序列号seq=u+1
CLOSE-WAIT:当被动关闭方接收到主动关闭方发出的FIN包,被动关闭方发出确认ACK包以后,进入CLOSE-WAIT状态,处于半关闭状态,此时主动关闭方没有数据要发送了,可是被动关闭方可能还有数据须要发送,主动关闭方必须接收它的数据。
TIME-WAIT:主动关闭方接收到被动关闭方发出的FIN包,向被动关闭方发出确认ACK包以后,进入TIME-WAIT状态。因为主动关闭方要等待被动关闭方接收到ACK包,报文最长的寿命时间为2MSL,若是在2MSL内被动关闭方没有接收到ACK包,会再次重发FIN包,这是一个等待机制。在通过2MSL事件后,主动关闭方才撤销TCB,进入CLOSE状态。
【报文最长的寿命时间:2MSL】
TCP:传输控制协议
UDP:用户数据报协议
TCP应用场景:
UDP应用场景:
- 数据包总量比较少的通讯,好比DNS、SNMP。
- 视频、音频等对实时性要求比较高的多媒体通讯。
- 广播通讯、多播通讯。
## 参考文章: http://www.javashuo.com/article/p-kbkappoe-hc.html
【吞吐量:单位时间内成功地传送数据的数量】
一、粘包:
应用程序所看到的数据是一个总体,或说是一个流,一条消息有多少字节对应用程序是不可见的【TCP协议是面向流的协议】,这也是容易出现粘包问题的缘由。
UDP是面向消息的协议,每一个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据
二、怎样定义消息:
能够认为一次性write/send的数据为一个消息【不管底层怎样分段分片,TCP协议层会把构成整条消息的数据段排序完成后才呈如今内核缓冲区。】
三、出现粘包的缘由:
由于接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所形成的。
1)客户端发:消息A,消息B ==> 消息A,消息B
2)客户端发:消息A,消息B ==> 消息A,消息A+B (消息A太大了 || 服务器不及时接收缓冲区的包,服务端下次再收的时候仍是从缓冲区拿上次遗留的数据)
3)客户端发:消息A,消息B ==> 消息A+B,消息B (消息A过小了,TCP为了提升传输效率,等缓冲区满才发送出去)
4)客户端发:消息A,消息B ==> 消息A+B(消息A和B都过小了,TCP为了提升传输效率,将消息A和B粘包一块儿发送)
四、粘包的解决方法:
接收端不知道发送端将要传送的字节流的长度,因此解决粘包的方法就是围绕,如何让发送端在发送数据前,把本身将要发送的字节流总大小让接收端知晓,而后接收端来一个死循环接收完全部数据
1)在两次send之间调用usleep休眠小一段时间来解决【缺点:传输效率大大下降,并且也并不可靠】
2)对数据包进行封包和解包:发送消息的时候,给每一个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,经过读取包首部的长度字段,便知道每个数据包的实际长度了。【缺点:会放大网络延迟带来的性能损耗】
3)发送端将每一个数据包封装为固定长度(不够的能够经过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就天然而然的把每一个数据包拆分开来。
4)在数据包之间设置边界,如添加特殊符号,这样,接收端经过这个边界就能够将不一样的数据包拆分开。
因为主动关闭方要等待被动关闭方接收到ACK包,报文最长的寿命时间为2MSL,若是在2MSL内被动关闭方没有接收到ACK包,会再次重发FIN包,这是一个等待机制。
在通过2MSL事件后,主动关闭方才撤销TCB,进入CLOSE状态。
系统用一个4四元组来惟一标识一个TCP链接:{local ip, local port,remote ip,remote port}
客户端(理论值):client发起TCP请求时会绑定一个端口,该端口是独占的,不能和其余TCP链接共享
端口的数据结构是unsigned short,端口0不能使用,因此216-1=65535 = TCP理论最大链接数
服务器端(理论值):最大TCP链接 = 客户端IP数×客户端PORT数 ≈ 232(ip最大值) × 216(port最大值) ≈ 248
实际值:对server端,经过增长内存、修改最大文件描述符个数等参数,单机最大并发TCP链接数超过10万是没问题的
## 参考文章 :http://www.javashuo.com/article/p-umwlekfk-eb.html
建立套接字【socket】,绑定端口【bind】,准备监听【listen(套接字,等待链接队列的最长长度)】
网络:两主机要通讯传送数据时,就要把应用数据封装成IP包,而后再交给下一层数据链路层继续封装成帧;以后根据MAC地址才能把数据从一台主机,准确无误的传送到另外一台主机。
ARP解析:数据链路层,经过IP寻找对方的MAC地址
IP寻址:网络层,根据目的IP地址,找到目的网络
完成了TCP的全双工通讯链接,打通了服务器到客户端的通讯通道
一、TCP链接以后就能够进行通讯了,客户端到服务器端的通讯,服务器端到客户端的通讯。
二、链接以后网线断了:select,epoll监测不到断开或错误事件,对于服务端来讲会一直维持着这个链接。
若是网线断开的时间短暂,在SO_KEEPALIVE设定的探测时间间隔内,而且两端在此期间没有任何针对此长链接的网络操做。当连上网线后此TCP链接能够自动恢复,继续进行正常的网络操做。
若是网线断开的时间很长,超出了SO_KEEPALIVE设定的探测时间间隔,或者两端期间在此有了任何针对此长链接的网络操做。当连上网线时就会出现ETIMEDOUT或者ECONNRESET的错误。你必须从新创建一个新的长链接进行网络操做。
【 服务器要想知道客户端的意外掉线,须要作心跳包:在客户端和服务器间定时通知对方本身状态的一个本身定义的命令字,按照必定的时间间隔发送。
心跳包:定时发送的一个自定义结构体(心跳包或心跳帧),让对方知道本身“在线”。 以确保连接的有效性。
TCP中已经为实现了一个叫作心跳的机制,若是设置了心跳,那TCP就会在必定的时间内发送你设置的次数的心跳,而且此信息不会影响你本身定义的协议。
】
三、链接以后出现服务器意外掉线之类的错误:例如Qt中监听错误信号QAbstractSocket::error(QAbstractSocket::SocketError socketError),当链接不上服务器的时候,会发送QAbstractSocket::ConnectionRefusedError错误信号,能够进行响应的处理
发送端在发送数据包以后就开启一个计时器,在必定时间内没有收到对方的ACK报文,则从新发送数据,直到发送成功。
影响超时重传机制协议效率的一个关键参数是重传超时时间(RTO)。
RTO的值被设置过大太小都会对协议形成不利影响。
链接往返时间(RTT),指发送端从发送TCP包开始到接收它的当即响应所消耗的时间。
一、建立socket:int socket(int domain/*IPv4*/, int type/*子协议*/, int protocol/*协议号,通常为0*/);
二、绑定IP和端口号bind:int bind(int sockfd/*套接字*/, const struct sockaddr *addr/*服务器端结构体*/, socklen_t addrlen/*结构体长度*/);
出现没法绑定setsockopt:setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt/*1*/,sizoef(opt));
三、作监听准备listen:int listen(int sockfd/*套接字*/, int backlog/*等待队列的容量*/);
四、被动监听客户端的链接请求并响应accept:int accept(int sockfd/*套接字*/, struct sockaddr *addr/*客户端结构体*/, socklen_t *addrlen/*结构体长度*/);
五、发送数据send:ssize_t send(int sockfd/*套接字*/, const void *buf/*缓存发送的消息*/, size_t len/*缓存大小*/, int flags/*是否阻塞*/);
六、接收数据recv:ssize_t recv(int sockfd/*套接字*/, void *buf/*缓存接收的消息*/, size_t len/*缓存大小*/, int flags/*是否阻塞*/);
七、关闭TCP链接:shutdown:int shutdown(int sockfd, int how/*如何断开链接*/); /*链接就会被当即断开*/
close :int close(int sockfd); /*一次性关掉读写,没法解决多个文件描述符指向了同一个链接时的关闭*/
在TCP三次握手的第三步中,若是服务器没有收到客户端的最终ACK确认报文,会一直处于SYN_RECV状态,将客户端IP加入等待列表,并重发第二步的SYN+ACK报文。重发通常进行3-5次,大约间隔30秒左右轮询一次等待列表重试全部客户端。另外一方面,服务器在本身发出了SYN+ACK报文后,会
预分配资源为即将创建的TCP链接储存信息作准备,这个资源在等待重试期间一直保留。更为重要的是,服务器资源有限,能够维护的SYN_RECV状态超过极限后就再也不接受新的SYN报文,也就是拒绝新的TCP链接创建。
一、DOS攻击:拒绝服务攻击,【服务资源包括网络带宽,文件系统空间容量,开放的进程或者容许的链接。这种攻击会致使资源的匮乏,不管计算机的处理速度多快、内存容量多大、网络带宽的速度多快都没法避免这种攻击带来的后果,使计算机或网络没法提供正常的服务】
最多见的DoS攻击有计算机网络宽带攻击和连通性攻击
二、DDOS攻击:分布式拒绝服务攻击
指借助于客户/服务器技术,将多个计算机联合起来做为攻击平台,对一个或多个目标发动DDOS攻击,从而成倍地提升拒绝服务攻击的威力。
面向链接、可靠的字节流传输
以老师给学生回答作例子:
(1)循环服务器模型:服务器再同一时刻只能响应一个客户端的请求
例子:当一个学生来上课,老师一直跟着这名学生,直到它解决问题离开教室,老师才能一直解决下一个学生的问题。
只要有学生进入教室,不管这名学生有没有问题,老师都不能帮助其余同窗解决问题,须要等到这名学生离开教室为止
⭐优势:简单易懂,没有同步、加锁等复杂状况,也没有进程建立等开销
由于UDP是短链接,没有一个客户端能够一直占用服务端(文件传输除外),服务器能够知足每个客户端的请求
(2)并发服务器模型:每个客户端的请求并非由服务器直接处理,并且由服务器的子进程/线程来处理,这样服务器能够在同一个时刻响应多个客户端的请求
例子:学校为了解决老师没法同时帮助多个学生解决问题,为每个学生安排了一名老师进行辅导,可是学校的资源有限,当学生的数量达到必定量时,学校没法承担那么大的开销。
⭐缺点:没有从根本上解决循环服务器处理效率低的问题(学校不能无限制的聘请无数个老师)
没有解决资源利用率低的问题(每位学生不可能一直有问题,可是每一个学生都占用了一名老师资源)
(3)I/O多路复用模型:内核一旦发现进程指定的一个或者多个IO条件准备读取时,它就通知该进程。
例子:因为资源利用率的问题,学校只聘请一名特别资深的教授(具备高端配置的服务器),这名教授处理问题的速度特别快
同时安排一名班长监听每一个学生有没有问题,若是有问题,班长就告诉教授,教授就快速的解决这名学生的问题,解决以后进入等待,直到监听到下一名学生出现问题为止
这样,每一个学生的问题都能被即时响应和解决,并且没有浪费资源
⭐优势:系统开销小,没必要建立和维护进程/线程,从而大大减少了系统的开销,同时解决了线程阻塞的问题(也可使用到并发服务器的设计中)
【由于socket套接字也是一种文件,socket句柄就是一个文件描述符,因此能够经过数据结构存储这些文件描述符,实现通讯的需求】
⭐优势:跨平台支持性好,几乎在全部平台上都支持
⭐缺点:
⭐优势:解决了select监听个数受限的问题
⭐缺点:须要作从用户态到内核态的转换,和数据拷贝,效率低,而后轮询每一个fd的状态,会经历屡次无谓的遍历
没有解决select中的性能问题,须要轮询pollfd来获取就绪的文件描述符,可是同一时刻可能只有少数的客户端有请求
⭐优势:不须要作用户区到内核去的转换,数据在共享内存中,epoll维护的红黑树在共享内存中,内核区和用户区共同操做共享内存
一、select内部用数组实现,poll用链表实现,epoll用红黑树来实现
二、select有最大监听个数的限制,poll和epoll没有
三、select和poll须要作从内核区到用户区的转换,数据拷贝,效率低
epoll不须要,epoll维护的树及其数据都在共享内存中
## 参考资料:老梁 + 肖家宝同窗的整理 + 个人笔记
(1)文件IO:不带缓存的IO,也是低级IO,操做系统提供的基本IO服务【不可移植,特定于LINUX平台/UNIX平台】
(2)标准IO:是标准函数包和stdio.h头文件中定义的部分,具备可移植性,提供了三种类型的缓冲区
## 参考文章:https://blog.csdn.net/big_bit/article/details/51804391
HTTP
特色:客户端发送的每次请求都须要服务器回送响应,在请求结束后,会主动释放链接。从创建链接到关闭链接的过程称为“一次链接”。
HTTPS = HTTP over SSL/TLS
是一个安全通讯通道
HTTP是应用层协议,TCP是传输层协议,在应用层和传输层之间,增长了一个安全套接层SSL(安全套接字层)/TLS(传输层安全协议)
SSL使用40 位关键字做为RC4流加密算法
HTTPS的做用:
内容加密 创建一个信息安全通道,来保证数据传输的安全;
身份认证 确认网站的真实性
数据完整性 防止内容被第三方冒充或者篡改
HTTP和HTTPS的区别:
## 参考文章:https://blog.csdn.net/WHB20081815/article/details/67640804
ARP:地址解析协议,ARP协议提供了网络层地址(IP地址)到物理地址(mac地址)之间的动态映射
(1)为何须要ARP协议
OSI模型把网络工做分为七层,每层互不干扰,只经过接口来进行通讯。IP地址在第三层网络层,MAC地址在第二层数据链路层。
协议在发送数据包时,数据包首先是被网卡接收到再去处理上层协议的,因此首先要封装第三层(IP地址)和第二次(MAC地址)的报头,可是协议仅知道目的地址IP地址,不知道MAC地址,可是不能跨层通讯
因此须要用到ARP协议
(2)工做过程:
## 参考文章:http://www.javashuo.com/article/p-qauslegb-de.html
URL:统一资源定位符,也就是网络资源的地址
【例子:你要去旅馆找一我的你必须知道他住在那个房间,这时候房间号就是你要找的人对应的地址,也就是这个场景下的URL。】
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
http:// 是协议
www.example.com 是域名,代表正在请求哪一个WEB服务器
:80 是端口号
/path/to/myfile.html 是网络服务器上资源的路径
key1=value1&key2=value2 是提供给网络服务器的额外参数
#SomewhereInTheDocument 是资源自己的另外一部分的锚点(书签)
## 参考文章:http://www.javashuo.com/article/p-yzjiyyfl-ep.html
1三、在浏览器中输入一串地址发生的过程
1四、DNS解析过程
1五、C/S模型的代码逻辑
1六、IP怎么寻址?
OSI七层模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
TCP/IP五层模型 应用层 传输层 网络层 数据链路层 物理层
TCP/IP四层模型 应用层 传输层 网络层 网络接口层
应用层:为特定应用程序提供数据传输服务。( TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet)
表示层:对上层信息进行变换,保证一个主机应用层信息被另外一个主机的应用程序理解,表示层的数据转换包括数据的加密、压缩、格式转换。
会话层:管理主机之间的会话进程,即负责创建、管理、终止。
传输层:提供端对端的接口。( TCP,UDP)
网络层:为数据包选择路由。(IP,ICMP,ARP,RARP)
数据链路层:传输有地址的帧,错误检测功能( SLIP,CSLIP,PPP,ARP,RARP,MTU)
物理层:以二进制数据形式在物理媒体上传输数据。 ISO2110,IEEE802,IEEE802.2