一、socket

IPC(Inter-Process Communication)叫做进程间通信,实现IPC的方式由很多,像共享内存、信号等。而socket就是IPC机制的一种实现,任何运行在用户空间内的进程需要通信时,就可以基于套接字编程的方式来调用套接字,就是通过向内核中的tcp/ip协议栈注册端口来实现不同或同一主机上的进程间通信。早期出现在BSD 4.2系统上,后来就被广泛的移植到Unix系统及Linux系统上。第一个被广泛使用的socket调用接口大概出现在1983年左右,所以目前套接字是一个很成熟、运用广泛的跨主机通信机制的实现方案

1. 套接字类型

(1)按使用的协议进行分类

  • SOCK_STREAM:tcp套接字,流式通信协议,使用tcp端口的套接字
  • SOCK_DGRAM:udp套接字,使用udp端口的套接字
  • SOCK_RAW:裸套接字,应用层的进程不使用tcp协议或udp协议,而是直接调用网络层封装报文后实现通信,这种就叫做裸套接字

(2) 套接字域(Socket Domain)

根据其所使用的不同IP地址家族,定义的套接字域,所以就有了这样的分类

  • AF_INET(Address Family):IPv4的套接字家族
  • AF_INET6:IPv6的套接字家族
  • AF_UNIX:这种套接字用于同一主机上不同进程间通信时使用,其不用调用tcp及udp或更低的层次进行报文封装,直接绕过TCP\IP协议栈,通过内核让二者进行通信,效率更高

套接字域中的三类套接字都提供了两种socket数据传输机制,流和数据报。

  • 流:就是tcp,实现可靠的传递、面向连接、多个报文发送之间无边界(不用标识报文从哪开始到哪里结束,因为建立了虚链路)
  • 数据报:提供不可靠的传递,因为它不检查、不重传、无拥塞控制等,传输报文有边界、非面向连接

2. 端口分配规则

tcp协议及udp协议的端口的范围均为0-65535,为了便于用户访问,IANA组织对其已经进行了划分

  • 0-1023:特权端口,永久的分配给固定服务使用,例如ssh、http
  • 1024-41951:注册端口,要求不严格,分配给程序注册为某应用使用
  • 41952-65535:被称作随机使用端口或私有端口,可供本地应用临时分配使用,其范围的定义在/proc/sys/net/ipv4/ip_local_port_range文件中

3. TCP协议的特性

tcp协议是目前互联网上最为广泛的使用套接字实现让两个不同的主机之间通信的机制,工作于内核中的,它的发送和接受分别是使用不同的信道完成的,有发送缓冲和接受缓冲

  • 建立连接:双方在通信之前需要先建立一个虚拟链路,通过三次握手完成
  • 将数据打包成段:将需要传输的数据包都分解成段,每一段都会包含一个校验和用于验证数据完整性,一般使用CRC-32算法(循环冗余检验法)
  • 确认、重传以及超时:根据校验和判断文件是否传输成功,如果存在错误那么这个段就会被丢弃并向发送方重新请求
  • 排序:把报文打包成段之后,这些报文都会被逻辑序号标识出这些数据位于整个数据流中的什么位置
  • 流量控制:为了避免发送方发送的过快把接受方压垮而设置的,通过滑动窗口告知发送方自己的接收缓冲还有多大
  • 拥塞控制:用慢启动的方式防止快速发送压垮整个网络,它会先发送几个报文看下接收效率,如果接收方很快就响应了说明网络并不拥堵,于是就慢慢增加发送量

4. 与套接字相关的系统调用

  • socket():创建一个套接字,也就是向内核申请一个套接字
  • bind():将一个进程和这个套接字绑定,表示要使用之意
  • listen():监听某个套接字
  • accept():接受请求
  • connect():请求连接建立
  • write():向套接字写文件,就相当于把这个数据发送给对端的主机
  • read():从缓冲中接受数据