为何会有socket,它起到什么作用
- 单节点的服务器,进程间的通信可归结为以下四类:
- 消息传递(管道、FIFO、消息队列)
- 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)
- 共享内存(匿名的和具名的)
- 远程过程调用(Solaris门和Sun RPC)
在本地可以通过PID唯一标识一个进程,但是网络中两个进程的PID很容易冲突。利用TCP/IP协议族的概念,IP标识节点,protocol+port标识进程,利用三元组(IP, protocol, port)就可以标识网络中不通的进程。
TCP/IP这个协议栈,需要向上层提供服务,也就像OS系统一样,会有各种抽象接口,如linux的read()、fork()等函数。结构图如下
从以上的结构图可知,socket跟TCP/IP并没有必然的联系,socket编程接口在设计的时候,就希望能其他的网络协议。socket的出现也就是为了更方便的使用TCP/IP协议而已,其对TCP/IP协议进行了抽象,形成几个最基本的操作,让网络间的进程通信更加简洁明了。比如:create、 listen、 accept、 connecte、 read、 write等。
从发展史来看,socket起源于UNIX,在Unix一切皆文件哲学的思想下,对于文件用打开、
读写、
关闭、
模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件。socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。
例如,如果一个程序创建了一个socket,并bind了80端口,就是向TCP/IP协议声明了其对80端口的占用。以后,所有目标是80端口的TCP数据包都转给该程序(因为使用socket,所以理应先有socket来处理)。通俗地讲,服务程序,在listen某个端口并accept某个请求连接后,会生成一个新的socket来对该请求处理。
Socket Definition:
A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to.
An endpoint is a combination of an IP address and a port number.
socket通信流程
socket是"打开—读/写—关闭"模式的实现,以使用TCP协议通讯的socket为例
- server端
- socket()用于创建一个socket描述符,它唯一标识一个socket。这个socket描述符跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。
- bind()把一个地址族中的特定地址赋给socket。也就是绑定服务端的IP跟端口
- 调用socket()、bind()之后就会调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会用accept()接收到这个请求。
- client端
- socket()初始化一个socket描述符文件句柄
- connect()的参数填上服务端的IP,端口系统会随机分配,如果server收到请求就会调用accept()接受这个请求。
- 数据传输
- 建立连接后,两者之间就调用,read()、write()函数传数据。
- 数据传输完成
- 传输完毕后,双方都调用close()函数,关闭socket链接服务。
- 网络层取出IP头,判断网络包下一步走向,比如是交给上层处理还是转发。当网络层认为这个包是要发送给本机后,会取出上层协议(TCP还是UDP),去掉IP包头,交给传输层处理。
- 传输层取出TCP头或者UDP头后,根据
<source-IP, source-port, destination-ip, destination-port>
四元组作为标识,找出对应的socket,并把数据copy到socket的接受缓冲区中。 -
最后,application就可以使用socket的相关接口,读取新接收到的数据了。
socket三次握手
- 客户端向服务器发送一个SYN J
- 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
-
客户端再想服务器发一个确认ACK K+1
socket四次断开
- 某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
- 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
- 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
-
接收到这个FIN的源发送端TCP对它进行确认。
网友评论