OSI模型
![](https://i-blog.csdnimg.cn/blog_migrate/1d9b8728c9dc6193d5714d569350e9d9.jpeg)
TCP三次握手
![](https://i-blog.csdnimg.cn/blog_migrate/b518f87d7e0d4bd88948e68d3f9ad3f7.jpeg)
-
握手过程
- 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
- 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
- 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
-
SYN攻击
-
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。
-
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。
-
SYN攻击是一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
# netstat -nap | grep SYN_RECV
-
TCP四次挥手
![](https://i-blog.csdnimg.cn/blog_migrate/eb1f9b937312f0fd81f22358e1a631b8.jpeg)
- 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
- 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
- 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
- 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
数据传输
- 单工 —> 只有一端可以发送数据
- 半双工 —> 两端都可以发送数据,但不可以同时发送数据
- 全双工 —> 两端可以同时发送数据 (TCP是全双工)
TCP通信原理
![](https://i-blog.csdnimg.cn/blog_migrate/c996ac16d22a59bffaa1b494a9782df0.jpeg)
-
每个TCP Socket的内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式及TCP的滑动窗口就是依赖于这两个独立的Buffer和该Buffer的填充状态。
-
接收端
若应用进程一直没有调用Socket的read方法进行读取,那么该数据会一直被缓存在接收缓冲区内。
Socket的read()所要做的工作,就是把内核接收缓冲区中的数据复制到应用层用户的Buffer里。 -
发送端
Socket的send()发送数据的时候,是将数据从应用层的Buffer中复制到Socket的内核发送缓冲区,然后返回。换句话说,send()返回时,数据不一定会被发送到对端。
什么是滑动窗口协议
![](https://i-blog.csdnimg.cn/blog_migrate/293a0ee4e9fadd1e0dc802accd656748.jpeg)
-
发送方和接收方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接收方确认,目的是控制发送速度,以免接收方的缓存不够大导致溢出,同时控制流量也可以避免网络拥塞。
-
图中的4,5,6号数据帧已经被发送出去,但是未收到关联的ACK,7,8,9帧则是等待发送。可以看出发送端的窗口大小为6,这是由接受端告知的(事实上必须考虑拥塞窗口cwnd,这里暂且考虑cwnd>rwnd)。
-
如果发送端收到4号ACK,则窗口的左边缘向右收缩,窗口的右边缘则向右扩展,此时窗口就向前“滑动了”,即数据帧10也可以被发送
BIO原理
- 如果接收缓冲区为空,则调用Socket的read方法的线程会阻塞,直到有数据进入接收缓冲区
- 如果待发送的数据长度大于发送缓冲区空余长度,则会阻塞在write方法上,直到发送缓冲区中的报文被发送到网络上
- 传统的Socket阻塞模式直接导致每个Socket都必须绑定一个线程来操作数据,参与通信的任意一方如果处理数据的速度较慢,会直接拖累到另一方,导致另一方的线程不得不浪费大量的时间在I/O等待上,所以这就是Socket阻塞模式的“缺陷”。但是这种模式在少量的TCP连接通信的情况下,双方都可以快速的传输数据,这个时候的性能是最高的。
阻塞VS非阻塞
-
阻塞
- 发送端 —> 线程轮询发送缓冲区是否可写
- 接收端 —> 线程轮询接收缓冲区是否可读
-
非阻塞
- 发送端 —> selector(多路复用器)产生可写事件通知线程发送缓冲区可写
- 接收端 —> selector(多路复用器)产生可读事件通知线程接收缓冲区可读
同步VS异步
-
同步
- 发送端 —> 线程写数据到发送缓冲区的同时不可以做其它事情(写数据的过程占用线程时间)
- 接收端 —> 线程从接收缓冲区读数据的同时不可以做其它事情(读数据的过程占用线程时间)
-
异步(epoll模型)
- 发送端 —> 线程向发送缓冲区发起写事件后立即返回,写数据的过程交给操作系统处理,OS写完后会通知线程(写数据的过程不占用线程时间)
- 接收端 —> 线程向接收缓冲区发起读事件后立即返回,读数据的过程交给操作系统处理,OS读完后会通知线程(读数据的过程不占用线程时间)
java通讯
![](https://i-blog.csdnimg.cn/blog_migrate/1646ddc73475c0c41089ae0c1f9f5646.jpeg)
Multicast(组播)
-
单播: 每次只有两个实体相互通信,发送端和接收端都是唯一确定的。从0.0.0.0到223.255.255.255属于单播地址(普通的TCP通信都属于单播)
-
广播: UDP属于广播
-
组播
序列化
-
serialVersionUID的作用
- 如果没有为指定的class配置serialVersionUID,java编译器会自动给这个class进行一个摘要算法,只要这个文件有任何改动,得到的UID就会截然不同
- 因此,如果我们自己指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原
-
transient关键字表示指定属性不参与序列化
-
要想父类对象也参与序列化操作,那么必须要让父类也实现Serializable接口
-
通过序列化操作实现深度克隆
-
主流的序列化技术有哪些?
JSON/Hessian(2) /xml/protobuf/kryo/MsgPack/FST/thrift/protostuff/Avro
https原理
![](https://i-blog.csdnimg.cn/blog_migrate/d0f516216a2da111ed4bd100be6113fb.jpeg)
- 浏览器发起往服务器的443端口发起请求,请求携带了浏览器支持的加密算法和哈希算法。
- 服务器收到请求,选择浏览器支持的加密算法和哈希算法。
- 服务器将数字证书返回给浏览器,这里的数字证书可以是向某个可靠机构申请的,也可以是自制的。
- 浏览器进入数字证书认证环节,这一部分是浏览器内置的TLS完成的:
(1) 首先浏览器会从内置的证书列表中索引,找到服务器下发证书对应的机构,如果没有找到,此时就会提示用户该证书是不是由权威机构颁发,是不可信任的。如果查到了对应的机构,则取出该机构颁发的公钥。
(2) 用机构的证书公钥解密得到证书的内容和证书签名,内容包括网站的网址、网站的公钥、证书的有效期等。浏览器会先验证证书签名的合法性(验证过程类似上面Bob和Susan的通信)。签名通过后,浏览器验证证书记录的网址是否和当前网址是一致的,不一致会提示用户。如果网址一致会检查证书有效期,证书过期了也会提示用户。这些都通过认证时,浏览器就可以安全使用证书中的网站公钥了。
(3) 浏览器生成一个随机数R,并使用网站公钥对R进行加密。 - 浏览器将加密的R传送给服务器。
- 服务器用自己的私钥解密得到R。
- 服务器以R为密钥使用了对称加密算法加密网页内容并传输给浏览器。
- 浏览器以R为密钥使用之前约定好的解密算法获取网页内容。
RPC
Remote procedure call protocal