Lazy loaded image
写一个简单的Socket函数
Words 1056Read Time 3 min
2022-6-8

1. Socket 定义

socket可以看成是用户进程内核网络协议栈的编程接口,是应用程序和tcp/ip协议的中间抽象层,设计模式里面这种类似于门面模式。
notion image
 

2. Socket API 编程模型

notion image
socket之间的连接可以分为三个步骤:服务端监听、客户端请求、连接确认,从上面的模型中我么你可以看到,通信主要是依靠“write-read / read-write ”这种模型来进行数据的读写,既然是这种模型,那么socket拥有这样的api。下面以tcp协议为例讲述一下socket的使用方式。

Socket 中 tcp 建立通信的三次握手机制

notion image
客户端和服务端进行通信,要遵循tcp的三次握手机制,如下:
  1. 客户端通过connect触发了连接请求,开始向服务器发送一个 SYN J 的数据包,接着connect函数进入阻塞状态等待返回。
  1. 服务端监听到客户端连接的请求,并接收来自客户端发送过来的 SYN J 数据包,接着调用 accept接收请求并向客户端发送 SYN K 和 ACK J+1的数据包,此时accept处于阻塞状态。
  1. 客户端收到 SYN K 和 ACK J+1的数据包时,connect函数返回,并对SYN K进行确认,确认完毕后,向服务器发送 SYN k+1。
至此服务器收到 SYN k+1 的包后,accept 函数返回。至此客户端和服务端的通信正式建立

TCP 服务端 API

TCP 客户端 API

 

Socket 中 tcp 的四次握手释放连接

notion image
  1. 当应用程序A方调用close函数主动关闭连接时,tcp会发送一个FIN M数据给应用程序B方。
  1. B方接到FIN M之后,对 FIN M进行确认并执行被动关闭操作,接着向A发送ACK M+1数据,FIN数据的接收意味着B在相应的连接上面再也接收不到数据了,一段时间后,B会调用close主动关闭连接。
  1. B关闭了与A之间的连接,发送FIN N给A。
  1. A 接收到FIN N后,发送ACK N+1给B。
至此两者之间的连接正式关闭。
 
那么为什么建立连接的时候只需要三次握手,而释放连接的时候却要经过四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
 
上一篇
Data Structure and Algorithm
下一篇
用面试拷问嵌入式技术栈

Comments
Loading...