OSI分层(7层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP/IP分层(4层):网络接口层、网际层、运输层、应用层。
五层协议(5层):物理层、数据链路层、网络层、运输层、应用层。
每一层的作用如下:
物理层:激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性。该层为上层协议提供了一个传输数据的物理媒体。传输原始比特流。
数据链路层:数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。
网络层:网络层负责对子网间的数据包进行路由选择。此外,网络层还可以实现拥塞控制、网际互连等功能。
传输层:第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传 输。此外,传输层还要处理端到端的差错控制和流量控制问题。
会话层:会话层管理主机之间的会话进程,即负责建立、管理、终止进程之间的会话。会话层还利用在数据中插入校验点来实现数据的同步。
表示层:表示层对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。表示层的数据转换包括数据的加密、压缩、格式转换等。
应用层:为操作系统或网络应用程序提供访问网络服务的接口
(2)TCP和UDP
TCP:传输控制协议,面向连接、可靠的字节流服务;全双工
有超时重发、检验数据、流量控制等
UDP:用户数据报协议,无连接,面向报文;速度快;可以是全双工
大多数TCP服务器都是并发的,大多数UDP服务器都是迭代的。
UDP和TCP应用场景的区别:
TCP一般用于对准确率要求较高速度可以相对慢的场合,比如账号密码远程登录,文件传输,发送接收邮件
UDP一般用于实时通信,如QQ聊天,视频,语音等等对速率要求比较高的场合
关于连接:
一个TCP协议连接其实就是在物理线路上创建的一条“虚拟信道”。这条“虚拟信道”建立后,在TCP协议发出FIN包之前(两个终端都会向对方发送一个FIN包),是不会释放的。正因为这一点,TCP协议被称为面向连接的协议!
UDP协议,一样会在物理线路上创建一条“虚拟信道”,否则UDP协议无法传输数据!但是,当UDP协议传完数据后,这条“虚拟信道”就被立即注销了!因此,称UDP是不面向连接的协议!
(3)网络各层协议
应用层: TFTP,SNMP,DNS这三个对应UDP;HTTP,POP3,FTP,SMTP,Telnet这5个对应TCP
传输层:TCP,UDP
网络层:IP,ICMP,RIP,OSPF,GGP,IGMP
链路层:传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层:以二进制数据形式在物理媒体上传输数据 ISO2110,IEEE802,IEEE802.2
TFTP和FTP区别:http://blog.csdn.net/woyaochenggong774/article/details/46324787
ARP协议:地址解析协议,将ip转换成硬件地址mac地址
ip地址和mac地址:ipv4地址32位,由TCP/IP协议指定给主机
mac地址48位,由网络设备制造商生产时写在硬件内部
NAT协议:将一个ip地址转换成多个内网地址,分给多个用户使用
(4)同步通信和异步通信
同步通信是一种比特同步通信技术,要求发收双方具有同频同相的同步时钟信号,只需在传送报文的最前面附加特定的同步字符,使发收双方建立同步,此后便在同步时钟的控制下逐位发送/接收;
异步通信在发送字符时,所发送的字符之间的时隙可以是任意的。但是接收端必须时刻做好接收的准备(如果接收端主机的电源都没有加上,那么发送端发送字符就没有意义,因为接收端根本无法接收)。发送端可以在任意时刻开始发送字符,因此必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位,以便使接收端能够正确地将每一个字符接收下来,还有一个奇偶校验位;
区别:
1.同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节。
2.同步通信效率高;异步通信效率较低(因为同步通信一次可以传输任意长的信息位数,但异步通信只能一字节)
3.同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。
4.同步通信可用于点对多点;异步通信只适用于点对点。
(5)TCP的黏包问题
TCP黏包问题指的是发送端以字节流的形式发送不同结构的数据包无明显边界导致接收方无法正确解析数据包
两个简单概念长连接与短连接:
(1)长连接
Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收。
(2)短连接
Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此种方式常用于一点对多点的通讯,比如多个Client连接一个Server。
如果利用TCP每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,在这种短连接的情况下就不会出现粘包问题,因为只有一种包结构,比如http协议包。但是在长连接的情况下,如果如果双方建立连接,需要在连接后一段时间内发送不同结构数据,如连接后,有好几种结构:
(1)”hello give me sth abour yourself”
(2)”Don’t give me sth abour yourself”
那这样的话,如果发送方连续发送这个两个包出去,接收方一次接收可能会是”hello give me sth abour yourselfDon’t give me sth abour yourself” 这样接收方就傻了,不知道接收的数据是什么,因为协议没有规定这么诡异的字符串,所以要处理把它分包,怎么分也需要双方组织一个比较好的包结构,所以一般可能会在头加一个数据长度之类的包,以确保成功接收,正确理解。
封包加上包头(里面包含报文长度信息)
(6)套接字和套接字对
标识一个端点的ip地址和端口号称为一个套接字;
标识一个TCP连接的两个端点的套接字称为一个套接字对;
(7)socket编程中的IO多路复用
一般用于需要同时处理多个描述符,防止轮询阻塞带来的系统开销,一般的场景:
---客户端需要同时处理交互式输入和套接字
---tcp服务器端要同时处理监听套接字和已连接套接字
---服务器要处理TCP和UDP
---服务器要处理多个服务或者多个协议
(8)名字与地址的转换
inet_pton和inet_ntop这类函数是在点分十进制和32位二进制ip地址之间的转换(格式转换)
gethostbyname(主机名->ip地址)和gethostbyaddr(ip地址->主机名)主要是在ip地址和主机名之间的转换(域名转换),利用了DNS域名系统。
面试题:DNS域名解析原理:http://blog.csdn.net/yipiankongbai/article/details/25031461
struct hostent{
char* h_name; //正式主机名
char** h_aliases; //别名数组
int h_addrtype; //协议家族AF_INET
int h_length; //地址长度:4字节
char** h_addr_list; //ip地址数组,因为一个主机可能有很多个ipv4地址
}
①主机名<------>ip地址
上面两个函数的原型:
struct hostent*gethostbyname(const char *hostname);
主要关心hostent.h_addr_list
struct hostent*gethostbyaddr(const char* addr, socklen_t len, int family);
主要关心hostent.h_name
②服务名<------>端口号
struct servent{
char* s_name;//服务名
char** s_aliases;//别名
int s_port;//端口号
char* s_proto;//使用的协议
}
struct servent* getservbyname(const char* servname, const char* protoname);
根据服务名得到端口号:
struct servent *sptr = getservbyname("ftp", "tcp");
struct servent* getservbyport(int port, const char *protoname);
根据端口号得到服务名:
struct servent *sptr = getservbyport(htons(21),"tcp");//htons将其转换成网络字节序
为了支持IPv6地址,出现了getaddrinfo函数,能够处理名字到地址和服务到端口两种转换。
(9)流量控制和拥塞控制
拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
TCP拥塞控制的实现方式
①慢启动与拥塞避免
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
cwnd<ssthresh时,慢开始(按照指数增长)
cwnd>ssthresh时,采用拥塞避免缓慢增长+1
发生了拥塞之后,ssthresh减半(乘法减小),cwnd变为1,重新慢启动
②快重传快恢复
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
快重传配合使用的还有快恢复算法,有以下两个要点:
①当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。
②考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。
流量控制:指点对点通信量的控制,是端到端正的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收
(10)关于HTTP(超文本传输协议)协议
HTTP协议是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。
http请求用法:http://blog.csdn.net/mingli198611/article/details/8055261
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer,基于SSL的HTTP协议)使用了HTTP协议,但HTTPS使用不同于HTTP协议的默认端口及一个加密、身份验证层(HTTP与TCP之间)。这个协议的最初研发由网景公司进行,提供了身份验证(利用数字证书)与加密通信(RSA加密对称秘钥的形式)方法,现在它被广泛用于互联网上安全敏感的通信。
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤
---(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
---(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
---(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
---(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
---(5)Web服务器利用自己的私钥解密出会话密钥。
---(6)Web服务器利用会话密钥加密与客户端之间的通信。
(11)http是一种无连接无状态的协议
理解:无连接指的是每次连接只处理一个请求。
但是,一台服务器同一时间处理请求越来越多,将会在建立和断开上花费太多时间;于是持久连接(http1.0)被提出;http1.1中持久连接变成了默认形式,并加入了pipelining(请求流水线)概念,防止串行阻塞后续请求。
无状态指的是协议对事务处理没有记忆能力,上一次会话和下一次会话没有联系。优点:解放服务器,不会造成不必要的连接占用;缺点:每次请求都会传输大量的重复内容信息(源,端。。。。。)
(12)HTTP消息结构以及通信步骤
步骤一:浏览器/客户端向服务器发送HTTP请求
get请求:
GET /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3
\r\n
post请求:
POST /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3
body data ...
连续两个\r\n表示header结束,后面都是body
步骤二:服务器向浏览器返回HTTP响应
200:成功;3**:重定向;4**:客户端发送请求有错误;5**:服务器处理请求内部出错
(13)HTTP请求方法
get和post区别:
①功能;get从服务器端获取数据,post向服务器端提交数据。
②服务器端解析;get提交的数据,服务端用request.QueryString获取;post提交的用request.Form获取。
③安全;get安全性较post较低,但get执行效率较快
④机制;get将参数数据放到URL后面,post将数据放到request body中。
-----get发送的时候只用发一个tcp包;post发送的时候有两个tcp包,先发header后发data
⑤大小;因为URL参数长度有限制,所以导致get的数据有大小限制;post方法理论上没有大小限制
总结:需要传送身份密码等敏感信息的时候用post,查询用get,添加用post
HEAD方法:与GET方法的相似,只不过HTTP只响应消息报头
(14)HTTP状态码
1**:消息
表示请求已经被接收,需要继续处理,临时响应的作用:
100 continue客户端应该继续发送请求
2**:成功
请求成功处理
200:请求成功,响应随此响应返回
201:请求以被实现
202:服务器以接收,当尚未处理
3**:重定向
需要客户端采取进一步操作才能完成,后续请求地址(重定向目标)在响应中给出
4**:客户端请求错误
对于客户端的请求服务端无法成功处理
400:Bad Request语义错误
401:Unauthorized当前用户未通过验证
403:Forbidden服务器已经理解请求,但是拒绝执行
404:Not Found请求的资源未找到
5**:服务器错误
服务器在处理请求的过程中有错误或者异常状态发生
500: Internal Server Error服务器内部出现未知错误
502:Bad Gateway从上游服务器接收到无效响应
503:Service Unavailable由于临时的服务器维护或者过载,服务器当前无法处理请求
(15)虚拟内存和虚拟地址
虚拟内存:虚拟内存是一种逻辑上扩充物理内存的技术。基本思想是用软、硬件技术把内存与外存这两级存储器当做一级存储器来用。虚拟内存技术的实现利用了自动覆盖和交换技术。简单的说就是将硬盘的一部分作为内存来使用。
虚拟地址:程序访问存储器所使用的逻辑地址称为虚拟地址,虚拟地址 (virtual address): 4G虚拟地址空间中的地址,程序中使用的都是虚拟地址。每一个进程都分配有一个4G的虚拟地址。
(16)DNS域名解析过程:
主机向本地域名服务器的查询一般都是采用递归查询。所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。
本地域名服务器向根域名服务器的查询的迭代查询。迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地服务器进行后续的查询。
假定域名为m.xyz.com的主机想知道另一个主机y.abc.com的IP地址。例如,主机m.xyz.com打算发送邮件给y.abc.com。这时就必须知道主机y.abc.com的IP地址。下面是上图a的几个查询步骤:
1、主机m.abc.com先向本地服务器dns.xyz.com进行递归查询。
2、本地服务器采用迭代查询。它先向一个根域名服务器查询。
3、根域名服务器告诉本地服务器,下一次应查询的顶级域名服务器dns.com的IP地址。
4、本地域名服务器向顶级域名服务器dns.com进行查询。
5、顶级域名服务器dns.com告诉本地域名服务器,下一步应查询的权限服务器dns.abc.com的IP地址。
6、本地域名服务器向权限域名服务器dns.abc.com进行查询。
7、权限域名服务器dns.abc.com告诉本地域名服务器,所查询的主机的IP地址。
8、本地域名服务器最后把查询结果告诉m.xyz.com。
整个查询过程共用到了8个UDP报文。
(17)关于HTTP长连接
HTTP1.1之后默认采用长连接,如果不想使用,设置头部:connection:closed;
一般可以设置长连接保持时间:connection: keep-alive(如果不设置下面两个则表示连接永久有效)
keep-alive : timeout = 超时时间
或者:max = 传输次数
keep-alive字段只有服务端设置才有效,这就意味着,会采用服务端设置的时间;
HTTP keep-alive和TCP keep-alive区别:
TCP的keep alive是检查当前TCP连接是否活着;HTTP的Keep-alive是要让一个TCP连接活久点。
TCP keep alive的表现:
当一个连接“一段时间”(可以进行设置)没有数据通讯时,一方会发出一个心跳包(Keep Alive包),如果对方有回包则表明当前连接有效,继续监控。