0%

Socket 通信原理

网络套接字(Socket)


前言

在同一台计算机,进程之间可以这样通信,如果是不同的计算机呢?网络上不同的计算机,也可以通信,有学传输层协议TCP、UDP,它们就是用来在不同计算机之间通行的协议,但它们毕竟只是协议,看不见摸不着,那怎们通过TCP、和UDP进行实际传输呢?

答案是使用网络套接字(Socket)

概述

Socket 中文意思为插座的意思,专业术语称之为套接字,它把 TCP/IP 封装成了调用接口供开发者调用,也就是说开发者可以通过调用Socket相关API来实现网络通讯。

Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通信,端口就像插座上的孔,端口不能同时被其他进程占用。而建立连接就像把插头插在这个插座上,创建一个 Socket 实例开始监听后,这个电话插座就时刻监听着消息的传入,谁拨通我这个“IP 地址和端口”,我就接通谁。

实际上,Socket 是在应用层和传输层之间的一个抽象层,它把 TCP/IP 层复杂的操作抽象为几个简单的接口,供应用层调用实现进程在网络中的通信。

Socket 起源于 UNIX,在 UNIX 一切皆文件的思想下,进程间通信就被冠名为文件描述符(file descriptor),Socket 是一种“打开—读/写—关闭”模式的实现,服务器和客户端各自维护一个“文件”,在建立连接打开后,可以向文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

Socket 接口

socket(): 创建socket

bind(): 绑定socket到本地地址和端口,通常由服务端调用

listen(): TCP专用,开启监听模式

accept(): TCP专用,服务器等待客户端连接,一般是阻塞态

connect(): TCP专用,客户端主动连接服务器

send(): TCP专用,发送数据

recv(): TCP专用,接收数据

sendto(): UDP专用,发送数据到指定的IP地址和端口

recvfrom(): UDP专用,接收数据,返回数据远端的IP地址和端口

closesocket(): 关闭socket

更多详细参考socket接口详解

通信过程

Socket 保证了不同计算机之间的通信,也就是网络通信。对于网站,通信模型是服务器与客户端之间的通信。两端都建立了一个 Socket 对象,然后通过 Socket 对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。

面向连接的 TCP 时序图:

从 TCP 连接的视角看 Socket 过程

TCP 三次握手的 Socket 过程:

  1. 服务器调用 socket()、bind()、listen() 完成初始化后,调用 accept() 阻塞等待;
  2. 客户端 Socket 对象调用 connect() 向服务器发送了一个 SYN 并阻塞;
  3. 服务器完成了第一次握手,即发送 SYN 和 ACK 应答;
  4. 客户端收到服务端发送的应答之后,从 connect() 返回,再发送一个 ACK 给服务器;
  5. 服务器 Socket 对象接收客户端第三次握手 ACK 确认,此时服务端从 accept() 返回,建立连接。

TCP 四次挥手的 Socket 过程:

  1. 某个应用进程调用 close() 主动关闭,发送一个 FIN;
  2. 另一端接收到 FIN 后被动执行关闭,并发送 ACK 确认;
  3. 之后被动执行关闭的应用进程调用 close() 关闭 Socket,并也发送一个 FIN;
  4. 接收到这个 FIN 的一端向另一端 ACK 确认。

代码

Java版可以看这个理解搞了两周Socket通信,终于弄明白了!


参考链接