一、tcp/Ip四层模型
1. 应用层:http、ftp(文件传输协议)、smtp(邮件传输协议)、telnet(tcp)| ping->ICMP
、DNS->UDP
2. 传输层:TCP UDP
3. 网络层:IP、ICMP、IGMP、ARP、RARP。
4. 网络接口层:
二、http协议详解:
1. http(超文本传输协议)
>2. 请求报文格式
请求行: GET http://www.baidu.com HTTP/1.1(方法名:url地址 协议版本+【回车换行】)
头部字段: User-Agent: Weget/1.12 (字段名称:【空格】 字段的值+【回车换行】)
connection: keep-alive->表示长连接
Content-Length: 128---->表示消息正文的长度
(【空行】)
请求数据: ——————————————————————————————
>3. 响应报文格式:
状态行: HTTP/1.1 200 OK (版本号 状态码)
响应头: Server: Apache-Coyote (字段名称:【空格】 字段的值+【回车换行】)
Content-Type: application/jason->内容的类型
Content-Length: 128------------->正文的长度
(【空行】)
相应正文:————————————————————————————————

4. 请求的方法:
GET : 从服务器获取资源,是安全的不会改变服务器的资源的状态
HEAD: 仅要求服务器返回头部信息
POST: 客户端向指定资源提交数据进行资源请求(例如提交表单或上传文件)
可能会导致已有资源的修改。
TRACE:回显服务器收到的请求->主要用于测试人员测试用

5. POST与GET方法的区别:
1. GET请求的数据会被附在URL之后,而POST是以将信息放在消息主体中,所以GET不安全
2. GET方法最多提交的数据大小为1024字节,而POST理论上无限制
3. GET方法只用于获取信息而并非修改信息,所以不会影响已有资源的状态
而POST可能修改已有资源的状态


6. 状态码 :
. 1XX:服务器接收到了请求行和头部信息,告知客户端继续发送数据
(客户端首先要先发送Except: 100-continue 头部字段告诉服务器自己还有数据要发送)
. 2XX:请求成功
. 3XX:资源被转移了,将被重定向
. 4XX:客户端出错
. 5XX:服务器出错

7. http的请求报文和响应报文为什么是这种格式?
为了避免粘包问题
1. 使用空行作为消息报头的结束
2. 以固定的方式读取消息报头,http报头的每一行都是一个完整的消息
3. 给出请求正文的大小,按大小读取Content-Length
8. TCP粘包问题:
1. 什么是粘包?
发送的后一包的头部紧紧粘着前一包的尾部,导致接收方不能正确的接收包的现象叫做粘包问题
. 只有在TCP长连接时才会发生粘包问题,短连接不会,因为短连接发送完一次数据就会断开链接
. UDP不会发生粘包问题,因为UDP是面向数据包的有固定的消息边界
. 无格式的文件等也不会发生粘包,因为只关心接收和发送
2. 为什么会出现粘包现象?
. 发送方原因:
由于TCP默认使用Nagle算法
————>只有让上一个分组得到确认才会发送下一个分组
Nagle算法
————>收集多个小分组,在一个确认到来时一起发送
正是Nagle算法导致了发送方可能的粘包问题
. 接收方原因:
TCP接收到分组后,将分组保存至接收缓冲区中,然后应用程序主动从缓冲区里读数据,这样一来
如果TCP接收分组的速率大于应用程序从缓冲区里读数据的速率,就会有多个包被放进缓冲区里,
就会出现粘包现象。
3. 怎么处理粘包现象?
. 发送方处理
可以通过关闭Nagle算法防止粘包出现,使用setsockopt函数里面的选项TCP_NODELAY,缺点:
会降低传输效率
. 接收端
没有相应机制
. 应用层处理:
应用层的处理简单易行,不仅能够解决接收方造成的粘包问题,还能解决发送方产生的粘包问题
解决方法就是循环处理:应用程序在处理从缓存读下来的数据时,读完一条数据,就应当循环读
取下一条数据,直到所有的数据都被处理;但是如何判断每条数据的长度呢?
1. 格式化数据:每条数据都有固定的格式(开始符,结束符)缺点,如果正文中有开始符或者
结束符就会失效。
2. 发送长度: 发送每条数据时,将数据的长度一并发送,比如可以选定每条数据的前四位是数据
的长度,应用层可以根据数据的长度来判断数据的开始和结尾。

9. get_line()
int get_line(int sock,char *buf,int size)
{
int i=0;
char ch='\0';
ssize_t ret=0;
while(i<size&&ch!='\n')
{
ret=recv(sock,&ch,1,0);
if(ret>0&&ch=='\r')
{
ssize_t s=recv(sock,&ch,1,MSG_PEEK);
if(ch=='\n')
recv(sock,&ch,1,0);
else
ch='\0'
}
buf[i++]=ch;
}
buf[i]='\0'
return i;
}

10. http长连接与短连接
connection: keep-alive
http1.0-->默认短链接
http1.1-->默认长连接
TCP在读写操作之前,server与client必须先建立一个连接,读写操作完成后,若双方不需要
连接就可以释放连接,建立连接三次握手,释放连接四次握手
http长连接实现原理:
保活计时器:
如果一个给定的链接在两小时内没有任何响应,则服务器就会想这个客户端发送一个探测
报文段,客户端必须处于以下四种状态之一。
1. 客户主机依然正常运行,并且服务器可达,客户的tCP响应正常,而服务器也知道
对方是正常的,则2小时后保活计时器复位
2. 客户主机已经崩溃且关闭,或者正在重启,则服务端将不能收到探测报文的响应
并在75秒后超时,服务器总共发10个这样的探测每个相隔75秒,若没有收到响应则认为
客户主机已关闭,就终止链接
3. 客户机正常运行,但是服务器探测报文不可达,类似2
4. 若客户端没有崩溃,但是已经重启,服务器会受到对其存活性的响应,该响应是一
复位,从而引起服务器对链接的终止。
长连接与短连接的应用场景:
长连接多用于操作频繁,点对点的通信,如数据库的链接用长连接
一般网站的访问用短连接,因为长连接比较耗费资源。
心跳包,心跳检测机制:
心跳包,每隔一段时间就会发起一次链接,查看客户端的链接是否还存在,一般在应用层实现
一般只有一个标志位(仅用来判断链接是否通畅)
比如微信就在应用层使用了心跳检测的机制。