Socket
操作系统
操作系统把内存划分为用户空间和内核空间,是为了安全和稳定,是一种权限分离的设计。
通过硬件指令把能做的事情分成两级,
内核空间(高权限):运行操作系统内核,可以直接访问所有硬件(如内存、磁盘、网卡)和执行特权指令。
用户空间(低权限):运行日常使用的普通程序,不能直接访问硬件,要调用内核提供的接口来请求服务。
参考:
https://juejin.cn/post/7011689981601120293
https://javaguide.cn/cs-basics/operating-system/operating-system-basic-questions-01.html
Socket
什么是Socket
Socket(套接字)是操作系统提供的一套网络通信编程接口(API)。
只要有操作系统的网络通信,就会涉及Socket,现代操作系统(Linux、Windows、macOS、Android、iOS)中,Socket是用户态程序访问内核网络协议栈的唯一API 接口。
主机和目标主机建立连接通道,主机的程序把数据塞进Socket,数据就能通过网卡传输到目标主机的程序里。
Socket必须包含的5个要素:传输协议、本地IP、本地端口、远端IP、远端端口。
Socket生命周期
以从客户端访问服务端一次完整的HTTP请求为例
1、建立连接:创建Socket、完成三次握手
操作系统内核创建一个套接字结构体new Socket(),将ip、端口、协议信息放入,通过TCP三次握手发起请求connect()
三次握手:
此时客户端监听开放端口,向服务端发送SYN(Synchronize),此时客户端状态变为SYN_SENT,Java线程阻塞在connect()系统调用上。服务端端口处于LISTEN状态,收到SYN。
服务端收到SYN后,内核检查半连接队列是否满,回复SYN+ACK(Acknowledge),服务端状态LISTEN→SYN_RCVD,并将此连接放入半连接队列。客户端收到SYN+ACK。
客户端收到SYN+ACK后,回复ACK,客户端状态SYN_SENT→ESTABLISHED,connect()返回解除阻塞,new Socket()执行完毕。服务端收到ACK,状态SYN_RCVD→ESTABLISHED,将连接从半连接队列移至全连接队列,此时服务端accept()返回,成功建立传输通道。
2、数据传输(发送 HTTP 请求与接收响应)
通道已建立,双方可以全双工通信
单工通信:数据只能单向传输,一方只能发,另一方只能收。收音机、电视机
半双工通信:数据可以双向传输,双方都能收发,但是无法一起发送,一方发另一方只能收。对讲机
全双工通信:数据可以同时双向传输,双方收发互不影响。网络聊天窗口
3、四次挥手(连接关闭)
短连接:客户端请求完,服务端知道文档传完直接调用close()发FIN
长连接Keep-Alive:服务端传完数据不关,等着客户端发下一个请求。客户端 5 秒没动静,服务端超时主动发 FIN(Fianl),不用再浪费内存。
先发起的一端要保持TIME_WAIT,保护端口资源稀缺的客户端,服务器主动关闭socket.close()
四次挥手:
服务端向客户端发送FIN,服务端状态:ESTABLISHED→FIN_WAIT_1。客户端收到FIN。
客户端收到FIN后,回复ACK,客户端状态:ESTABLISHED→CLOSE_WAIT。服务端收到ACK。
服务端收到ACK后,FIN_WAIT_1→FIN_WAIT_2,此时 TCP 半关闭,服务端不能再发数据,但客户端还可以发。客户端应用层read()返回-1知道不再发送,向服务端发送FIN,客户端状态:CLOSE_WAIT→LAST_ACK。服务端收到FIN。
服务端收到FIN后,回复最后一个ACK,进入TIME_WAIT。客户端收到ACK,彻底关闭。服务端TIME_WAIT超时状态变为 CLOSED。
OSI七层协议
物理层
数据链路层
网络层
传输层
会话层
表示层
应用层
TCP/IP四层协议
应用层(应用层 + 表示层 + 会话层)
传输层
网络层
网络接口层(数据链路层 + 物理层)

浙公网安备 33010602011771号