1.理解套接字[socket]
套接字大致分为两种:TCP和UDP,可以把TCP套接字理解为电话机,UDP套接字理解为信件。在Linux世界里,socket被认为是一种文件,使用文件I/O的相关函数;Windows中socket跟文件是不同的。
采用打电话的方式,来简单的理解TCP套接字。
服务端TCP
- 安装电话机-调用socket函数
- 分配可被拨打的电话号码-调用bind函数
- 等着电话响-调用listen函数
- 电话响了接起电话-调用accept函数
客户端TCP
- 安装电话机-调用socket函数
- 拨打电话-调用connect函数
TCP的特征
- 传输过程中数据不会消失
- 按序传输数据
- 传输的数据不存在数据边界
TCP的定义
- 可靠的、按序传递的、基于字节的、面向连接的数据传输方式的套接字
TCP数据的收发
- tcp的读写都有缓冲,通过缓冲大小的滑动窗口控制数据流
- write函数的返回时间点:在数据移到输出缓冲时
- 关闭套接字,输出缓冲继续传递,输入缓冲直接丢失
- 三次握手[SYN]:(SEQ,ACK)->[SYN+ACK]:(SEQ,ACK)->[ACK]:(SEQ,ACK)
- 四次挥手[FIN]:(SEQ,ACK)->[ACK]:(SEQ,ACK),[FIN]:(SEQ,ACK)->[ACK]:(SEQ,ACK)
采用发信件的方式,来简单的理解UDP套接字。
服务端UDP
- 安装信箱-调用socket函数
- 分配可被访问的信箱地址-调用bind函数
- 收信件-调用recvfrom函数
- 发信件-调用sendto函数
客户端UDP
- 安装信箱-调用socket函数
- 收信件-调用recvfrom函数
- 发信件-调用sendto函数
UDP的特征
- 强调快速传输而非传输顺序
- 传输的数据可能丢失也可能损毁
- 传输的数据有数据边界
- 限制每次传输的数据大小
UDP的定义
- 不可靠的、不按序传递的、基于消息的、不连接的、以数据的高速传输为目的的套接字
2.进程间通信
- 通过管道实现
- IPC实现
3.优雅的断开TCP连接
采用close函数,将同时关闭读写通道,优雅的断开可以采用shutdown函数,可以选择只关闭读或写通道,使TCP处于半关闭状态。
4.TCP套接字的可选项
- socket的SO_REUSEADDR可以在tcp四次挥手,处于time-wait状态时端口重新分配给新的socket。
- TCP_NODELAY用于控制socket套接字是否使用Nagle算法,默认是使用的。即在收到ack消息后,才会发送下一条数据,防止网络数据包过多产生负载。有些场景禁用Nagle算法可以提高传输速度。
5.IO复用
5.1.select
- 主动观察,速度慢
- 循环检查
- 跨操作系统兼容性强
5.2.epoll
- linux下的,被动得知
- 条件触发:只要输入缓冲有数据就一直通知该事件
- 边缘触发:输入缓冲收到数据时仅注册1次该事件,即使输入缓冲区还有数据,也不会再次注册
5.3.IOCP
- windows下的
参考:《TCP/IP网络编程》