一、TCP和UDP协议
1、报文格式
1.1、TCP协议
源/目的端口号:表示数据是从哪个进程来,到哪个进程去。
URG:紧急指针是否有效。
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光 包含TCP首部,也包含TCP数据部分。
1.2、UDP协议
16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度。
如果校验和出错,就会直接丢弃。
2、TCP、DUP的对比
TCP |
UDP |
有连接 |
无连接 |
可靠传输(尽自己最大可能吧数据有序发给对方,但不能保证一定能发给对方,即使发送不过去也会有反馈) |
不可靠传输(没有任何安全机制) |
面向字节流(发送端一次发送多少字节,接收端也必须一次一次接收多少字节,不能拆分接收和发送) |
面向数据报(应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并) |
有缓冲接收区和发送接收区 |
有接收缓冲区,无发送缓冲区 |
大小不限 |
最大64K |
PS:更具体可参考:http://t.csdn.cn/YbmS9
粘包问题可参考:http://t.csdn.cn/pVIiN
3、TCP协议复杂的原因
3.1、要保证可靠性
3.1.1、校验和
3.1.2、序列号(按序到达)
3.1.3、确认应答:TCP将每个字节的数据都进行了编号。即为序列号。 每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开 始发。
3.1.4、超时重发:如果没有收到对方的回应,会过一段时间再次发送。
3.1.5、连接管理:在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接。
3.1.6、流量控制:接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制。
3.1.7、拥塞控制:虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。
3.2、尽可能提高性能
3.2.1、滑动窗口:是一种流量控制技术,存在于数据链路层,也存在于传输层。窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。下图的窗口大小就是4000个字节(四个段)。发送前四个段的时候,不需要等待任何ACK,直接发送;收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;窗口越大,则网络的吞吐率就越高;
3.2.2、快速重传
3.2.3、延迟应答:数量限制:每隔N个包就应答一次;时间限制:超过最大延迟时间就应答一次。
3.2.4、捎带应答
3.3、其它
定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)
二、TCP连接管理
1、三次握手:
检验双方通信、网络是否正常,在此基础上才能进行通信。
PS:SYN为1:申请建立连接。ACK为1:响应。ack:确认号。
Q1:俩次握手是否可行?==》不可行。服务器会不确定客户端是否成功和它建立了连接。
Q2:四次握手是否可行?==》可以,但没必要。TCP通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都要发送SYN确保对方具有通信的能力。第一次握手是客户端发送SYN,服务端接收,服务端得出客户端的发送能力和服务端的接收能力都正常;第二次握手是服务端发送SYN+ACK,客户端接收,客户端得出客户端发送接收能力正常,服务端发送接收能力也都正常,但是此时服务器并不能确认客户端的接收能力是否正常;第三次握手客户端发送ACK,服务器接收,服务端才能得出客户端发送接收能力正常,服务端自己发送接收能力也都正常。
2、四次挥手:
通信结束了就需要断开连接。
PS:FIN为1:断开连接。
Q1:三次挥手是否可行?==》三次挥手和四次挥手都是有可能的,若中间两次的时间差很小,是有可能合二为一的。
PS:更具体可参考:http://t.csdn.cn/MepcL
三、TCP状态
1、状态概念
LISTEN:服务器启动成功,端口绑定成功,开始监听客户端的链接请求。相当于所有的已经准备就绪,然后随时等待通信。
CLOSED:初始状态,表示TCP连接是“关闭的”或者“未打开的”。
CLOSING:连接断开期间,一般是客户端发送一个FIN,然后服务器回复一个ACK,然后服务器发送完数据后再回复一个FIN,当客户端和服务器同时接受到FIN时,客户端和服务器处于CLOSING状态,也就是此时双方都正在关闭同一个连接。
ESTABLISHED:表示客户端已经连接成功,可以进行通信了。
CLOSE_WAIT:当服务器发送连接断开确认ACK之后但是还没有发送自己的FIN之前的这段时间,服务器处于该状态。
TIME_WAIT:当客户端收到了服务器发送的FIN并且发送了自己的ACK之后,客户端处于该状态。
PS:具体可参考:2020-09-19:TCP状态有哪些? - 知乎 (zhihu.com)
2、状态转换
PS:为什么TIME_WAIT的时间是2MSL?
===》MSL是TCP报文的最大生存时间,因此若持续存在2MSL,就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启,可能会收到来自上一个进程的迟到的数据,但是这种数据很可能是错误的);同时也是在理论上保证最后一个报文可靠到达。
四、HTTP协议
1、概念
1.1、HTTP:超文本传输协议,是一种应用层协议。HTTP 往往是基于传输层的 TCP 协议实现的(HTTP1.0, HTTP1.1, HTTP2.0 均为TCP, HTTP3 基于 UDP 实现)。
1.2、协议格式
PS:HTTP报文中出现空行,是因为HTTP在传输层依赖于 TCP ,TCP是面向字节流的,若没有这个空行,就有可能会出现“粘包问题”。 空行就相当于是 "报头的结束标记", 或者是 "报头和正文之间的分隔符"。
2、URI 和 URL
2.1、URI
URI,是 uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个 URI 来定位的 。
URI一般由三部组成:
访问资源的命名机制;存放资源的主机名;资源自身的名称,由路径表示,着重强调于资源。
2.2、URL
URL,是 uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
URL一般由三部组成:
协议(或称为服务方式);存有该资源的主机IP地址(有时也包括端口号);主机资源的具体地址。如目录和文件名等。
eg:
PS:浏览器输入URL后发生的过程可参考:http://t.csdn.cn/8wuDv
3、HTTP 的请求方法
3.1、请求方法
http1.0,三种:post,get,head
http1.1,八种:post,get,head,options,put,delete,trace,connect
PS:具体可参考:http://t.csdn.cn/2fzXp
PS:GET 和 POST 的区别:(总体而言,二者没有本质区别。具体来说,GET能使用的场景,POST也能使用;POST使用的场景,也能替换成 GET。)
(1)语义不同:GET一般用于获取数据,POST一般用于提交数据。
(2)GET一般没有 body ,参数通过查询字符串(query string)来传递;POST一般有 body ,没有查询字符串。
(3)GET请求一般是幂等(对于同一个请求,在不同时刻,结果是一样的)的;POST请求一般是不幂等的。
(4)GET可以被缓存;POST不能被缓存。
3.2、HTTP请求的构造
3.2.1、通过浏览器直接访问。
3.2.2、通过 form表单构造。
缺点:会涉及到页面的跳转。
3.2.3、通过 ajax构造。
(1)ajax是一种JavaScript给服务器发送HTTP请求的方式,属于异步等待,是Jquery提供的一种方法。
PS:
(2)ajax下载:复制连接;浏览器打开;页面上右键另存为;下载到本地。
(3)实现
<script src="jquery.min.js"></script>
<script>
// ajax方法只有一个参数,这个参数是一个对象,该方法就通过这个对象来构造一个http请求
$.ajax({
type:"get",
//form表单使用的是method,ajax用的是type
url:"http://abcd.com",
successful:function(){
// 一个回调函数, 当http响应成功(状态码为2xx/3xx)就会调用这个方法
console.log("ajax success");
},
error:function(){
//响应失败时会执行的函数
console.log("ajax false");
}
});
</script>
PS:ajax不允许跨域。例如:百度的页面去访问百度的其他页面,这种不是跨域。跨域的处理:需要对方的服务器允许跨域。
3.2.4、通过Java socket 构造
3.2.5、通过Postman 构造
(1)下载(下哪个版本都可以)
下载地址:下载邮递员 |免费开始 (postman.com)
进入后的初始界面:
(2)进行操作:
进行测试的代码:
hello.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<form action="getParam" method="post">
<input type="text" name="name">
<input type="text" name="age" >
<input type="submit" value="提交">
</form>
</body>
</html>
ParamServlet:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/getParam")
public class ParamServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String age = req.getParameter("age");
resp.setContentType("text/html;charset=utf-8");
if (Integer.parseInt(age)<1){
resp.getWriter().write("婴儿");
}else {
resp.getWriter().write("其他");
}
System.out.println("name:"+name+",age:"+age);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String age = req.getParameter("age");
resp.getWriter().write("name:"+name+",age:"+age);
}
}
(3) 发送 get 请求:
(4)发送 post 请求:
PS:get 和 post 请求写参数的位置不同
PS:更具体还可参考:
4、HTTP状态码
PS:具体可参考:http://t.csdn.cn/rZXJC
常见状态码:
200:表示访问成功。
301:永久重定向。当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址。
302:要求客户端临时重定向。
403 Forbindden:表示访问被拒绝,没有权限。有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问),如果用户没有登陆直接访问,就容易见到 403。服务器收到请求但拒绝提供服务。
404 Not Found:URL表示的资源不存在,没有找到资源。
500:服务器内部出错(代码有bug)。
504:当服务器负载较大时,服务器处理单条请求时消耗的时间就会很长,就可能会导致超时的情况。
505:服务器不支持的请求的HTTP协议的版本。