Carl
  • 3.3k

tcp ip高效编程 笔记

 阅读约 8 分钟

CS架构与对等实体

CS位置 备注 特点 举例
同一机器 数据会被环回,并不会放到网络设备输出队列中 几乎没有网络延迟和丢包 自己开发web程序调试
同一局域网内 极少没有网络延迟和丢包 打印机
不同网络 位于广域网 途径的路由器如果队列空间耗尽,就会导致丢弃分组,进而导致重传。重传又会引起分组的重复和乱序。 真实环境

基本套接字API回顾

SOCKET socket (int domain, int type, int protocol)
// 成功返回套接字描述符,失败时返回-1

套接字API与协议无关。

domain是个常量,表示通信域,有以下两个

  • AF_INET 用于因特网
  • AF_LOCAL 用于同一台机器上的IPC通信,即进程间通信

type说明套接字的类型,有常见的以下几种

  • SOCK_STREAM 提供可靠,全双工,面向连接的字节流,例如TCP
  • SOCK_DGRAM 提供不可靠,尽力而为的数据服务,例如UDP
  • SOCK_RAW 允许对IP层的某些数据进行访问,例如监听ICMP报文

protocol说明使用哪种协议,对tcp/ip来说,可以直接由type字段隐式说明,参数被设置为0

int connect (SOCKET s, const struct socketaddr *peer, int peer_len)
// 成功时返回0, 失败时返回非0
  • s: 套接字描述符
  • peer: 是一个地址结构,存储对等实体的地址和其他信息
  • peer_len; 是地址结构的长度

connect一旦建立起来,就可以传输数据。在unix中,套接字描述符可以像文件描述符那样调用read和write。但是windows

int recv (SOCKET s, void *buf, size_t len, int flags)
int rend (SOCKET s, cosnt void *buf, size_t len, int flags)

参数s, buf, len和read, write参数一样。flags通常和系统有关。
unix和win都支持以下flag

  • MSG_OOB 收发紧急数据
  • MSG_PEEK 查看输入数据,但是不从缓冲区删除数据。俗称瞥一眼
  • MSG_DONTROUTE 绕过通常的选路函数,通常只有选路函数使用,或用于诊断

理解面向连接和无连接协议的区别

  • 面向连接和无连接,指的都是协议,不是物理介质,是指数据在介质上如何传输
  • 本质区别是,对于无连接协议,每个分组的处理都是独立的。对于面向连接的协议,分组还要维护后续分组的相关信息。
  • 无连接协议是面向连接协议的基础

无连接协议就像是寄信,每封信都有自己的收件人地址,你可以同时给多个人寄信。邮局处理信件也不会管每封信之间的关系。

面向连接的协议就像是打电话,一个人先拨号,等另一个人说喂,然后自己在说我是某某某。说完话了,一个人会说,拜拜,另一个也会说拜拜。 有时候你听不清楚对方在说什么,还会说:麻烦你在说一遍,我没听清。或者:你说的太快了,麻烦说慢一点。

--------
应用程序
--------
TCP和UDP
--------
  IP
--------
物理接口
--------

TCP的每个分组成为段(segment), 是放在IP数据包中发送的。但是IP数据报并不保证数据的可靠到达。所以TCP必须自己实现可靠性。

TCP使用三个功能实现可靠性

  • 校验和:校验和用来校验数据有没有被中途损坏,保证安全性
  • 序列号:每个段都有自己的序号,用来重新排列乱序的段,保证顺序性
  • 确认重传机制: 保证每个段都被对方收到,保证可靠性

TCP的三个功能中,确认重传机制最为复杂。

TCP接收窗口

图片描述

  • 左边箭头表示窗口的左边界,所期望下一个字节的序列号
  • 右边箭头表示窗口的右边界,表示TCP缓冲区所能容纳字节的最大编号,用来防止缓冲区溢出
  • TCP到达时,所有序列号在窗口范围之外的,都会被直接丢弃
  • 如果段中的第一个字节序号是期望的字节号,就通知应用程序有数据可读。并且将窗口向右滑动

TCP发送窗口

图片描述

  • 发送窗口分为两个部分,已经发送出的但是还没有收到确认的,还有可以发送但还没有发送的
  • 在4-7字节已经发送出去之后,TCP会启动一个RTO(retransmission timeout)超时重传定时器,如果定时器超时之前这四个字节没有被确认,就会重传这四个字节。要注意重传的自己可以要比四个字节要多。
  • 重传并不意味着数据没有到达目的地,也有可能是ACK丢失

TCP是一种流协议

TCP是一种流协议,并没有固定的报文和报文流的概念。

发送两次报文并不发送两个独立的实体,两次调用send, 只是将数据交给底层TCP/IP栈。至于底层是如何发送这两个数据的,由底层自己决定。

图片描述

底层将数据发出去有很多决定因素

  • 发送窗口
  • 拥塞窗口
  • 路径最大传输单元
  • 输出队列中有多少数据

图片描述

不要低估TCP的性能

TCP并不是绝对可靠

  • 故障模式
  • 对等实体崩溃
  • 网络中断

不要把OSI七层模型太当回事

实际上OSI模型由很多缺点,本质上说OSI协议已经停用了。OSI模型是理想,TCP/IP才是现实。

理解TCP写操作

  • 从应用程序角度看,send
  • 从TCP角度看,慢启动,ng算法

TIME-WAIT

图片描述

  • 通常,只有主动关闭连接的一方会进入TIME-WAIT阶段
  • RFC 793将MSL定义为两分钟,那么2MSL就是4分钟。实际的操作系统可以将MSL设置为更低的值,如30秒。
  • 如果连接处于TIME-WAIT阶段,又有分组到达,就会重启2MSL定时器。

使用TIME-WAIT的目的

  • 维护连接状态,以防主动发起连接关闭的哪一方最后一个ACK丢失造成另一端发送FIN
  • 耗尽网络中所有此连接的走失提供时间

想一想,如果主机1在发出ACK之后立即关闭了连接,会发生什么事?

AB分别为主机

有 TIME-WAIT状态时,如果ACK丢失,那么B会重发FIN, A处于TIME_WAIT阶段时,再次收到FIN, 那么就会再次发送ACK, 并重启激动2MSL计时。

图片描述

无TIME-WAIT状态时, 主机A的收到FIN后,立即释放端口,那么该端口处于未监听状态。当数据被发送到为监听的端口时,发送方会收到链接重置的报文。

图片描述

无TIME-WAIT状态时, 主机A的端口已经被新的应用程序占用,新的连接的数据可能被迟来的数据破坏。

图片描述

TCP的状态转移图

  • TCP一共有11中状态
  • 左下角虚线方框中是主动关闭方关闭时会经历的状态转移

图片描述

尽可能写入一个大块数据,而不是频繁的写入小块的数据

参考书籍

阅读 323发布于 1月30日
推荐阅读
洞香春
用户专栏

前端知识记录

756 人关注
125 篇文章
专栏主页
目录