tcp ip高效编程 笔记

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中状态
  • 左下角虚线方框中是主动关闭方关闭时会经历的状态转移

图片描述

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

参考书籍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
说明--TCPIP高效编程:改善网络程序的44个技巧 PDF中文版带书签-目录 下载链接放在文档中 《TCP/IP高效编程:改善网络程序的44个技巧》是TCP/IP 领域历久弥新的经典著作,网络编程人员必备,对TCP/IP 网络编程中存在的各种问题进行了全面解析,旨在帮助读者深入透彻地理解TCP/IP 网络编程。本书组织方式比较特别,正文部分包括4 章,将网络编程中存在的常见问题组织成44 个技巧,探讨问题的过程中构建并运行了多个程序,并且指出了代码的源地址,便于读者查看。全书以技巧的形式解答了日常工作中遇到的经典问题,将本书作为手册使用,极其方便。 《TCP/IP高效编程:改善网络程序的44个技巧》主要面向有一定经验的初学者或中级网络程序员,也可作为计算机相关专业人士的参考读物。 ================ 原书名:Effective TCP/IP Programming: 44 Tips to Improve Your Network Programs 原出版社: Addison-Wesley Professional 作者: (美)Jon C. Snader 译者: 陈涓 赵振平 作译者 Jon C.Snader:TCP/IP专家,Paradigm 4的资深软件工程师。他的工作领域包括通信、网络、编译器开发、操作系统以及无线网络控制器等。最近主要从事公共安全市场的报文交换系统方面的工作。 陈涓 1997年毕业于南京通信工程学院,获得通信与信息系统方向硕士学位。留校任教至今,从事网络应用方面的工作。 赵振平 1998年毕业于南京大学计算机科学系,获得操作系统网络方向硕士学位。目前任职于南京信风软件有限公司(www.greatbit.com),从事网络安全和多媒体方面的工作。 目录 《TCP/IP高效编程:改善网络程序的44个技巧》 第1章 概述 1 1.1 几个约定 1 1.2 本书其余部分的内容介绍 2 1.3 客户端—服务器结构 4 1.4 对基本套接字API的回顾 5 1.5 小结 12 第2章 基本概念 13 2.1 技巧1:理解面向连接和无连接协议之间的区别 13 2.2 技巧2:理解子网和CIDR的概念 18 2.2.1 分类编址 18 2.2.2 子网划分 21 2.2.3 CIDR 26 2.2.4 子网划分和CIDR的状态 27 2.2.5 小结 27 2.3 技巧3:理解私有地址和NAT 28 2.4 技巧4:开发并使用应用程序“框架” 30 2.4.1 TCP服务器框架 31 2.4.2 TCP客户端框架 36 2.4.3 UDP服务器框架 38 2.4.4 UDP客户端框架 39 2.4.5 小结 41 2.5 技巧5:套接字接口比XTI/TLI更好用 41 2.6 技巧6:记住,TCP是一种流协议 43 2.7 技巧7:不要低估TCP的性能 50 2.7.1 UDP源程序与接收程序 52 2.7.2 TCP源程序及接收程序 53 2.7.3 小结 59 2.8 技巧8:避免重新编写TCP 59 2.9 技巧9:要认识到TCP是一个可靠的,但并不绝对可靠的协议 61 2.9.1 可靠性——是什么,不是什么 61 2.9.2 故障模式 63 2.9.3 网络中断 63 2.9.4 对等实体崩溃 64 2.9.5 对等实体的主机崩溃 68 2.9.6 小结 69 2.10 技巧10:记住,TCP/IP不是轮询的 69 2.10.1 保持活跃 70 2.10.2 心跳信号 71 2.10.3 另一个例子 76 2.10.4 小结 81 2.11 技巧11:提防对等实体的不友好动作 81 2.11.1 检测客户端的终止 82 2.11.2 检测无效输入 84 2.11.3 小结 88 2.12 技巧12:成功的LAN策略不一定能推广到WAN中去 88 2.12.1 性能问题举例 88 2.12.2 隐含错误举例 89 2.12.3 小结 93 2.13 技巧13:了解协议是怎样工作的 93 2.14 技巧14:不要把OSI七层参考模型太当回事 94 2.14.1 OSI模型 95 2.14.2 TCP/IP模型 96 2.14.3 小结 98 第3章 构建高效且健壮的网络程序 99 3.1 技巧15:理解TCP的写操作 99 3.1.1 从应用程序的角度看写操作 99 3.1.2 从TCP角度看写操作 100 3.1.3 小结 103 3.2 技巧16:理解TCP的有序释放操作 103 3.2.1 shutdown调用 104 3.2.2 有序释放 106 3.2.3 小结 110 3.3 技巧17:考虑用inetd来装载应用程序 111 3.3.1 TCP服务器 111 3.3.2 UDP服务器 114 3.3.3 小结 118 3.4 技巧18:考虑用tcpmux为服务器“分配”知名端口 118 3.5 技巧19:考虑使用两条TCP连接 126 3.5.1 单连接结构 127 3.5.2 双连接架构 128 3.5.3 小结 133 3.6 技巧20:使应用程序成为事件驱动的(1) 133 3.7 技巧21:使应用程序成为事件驱动的(2) 140 3.8 技巧22:不要用TIME-WAIT暗杀来关闭一条连接 147 3.8.1 它是什么 147 3.8.2 为什么要使用它 149 3.8.3 TIME-WAIT暗杀 150 3.8.4 小结 151 3.9 技巧23:服务器应该设置SO_REUSEADDR选项 151 3.10 技巧24:可能的话,使用一个大规模的写操作,而不是多个小规模的写操作 155 3.10.1 禁用Nagle算法 158 3.10.2 将写操作合并起来 159 3.10.3 小结 161 3.11 技巧25:理解如何使connect调用超时 162 3.11.1 使用告警 162 3.11.2 使用select 164 3.11.3 小结 167 3.12 技巧26:避免数据复制 167 3.12.1 共享内存缓冲区 168 3.12.2 一个共享内存缓冲区系统 169 3.12.3 一个UNIX实现 171 3.12.4 一个Windows实现 175 3.12.5 小结 179 3.13 技巧27:使用前将结构sockadddr_in清零 179 3.14 技巧28:不要忘记字节的性别 180 3.15 技巧29:不要将IP地址或端口号硬编入应用程序中 182 3.16 技巧30:理解已连接的UDP套接字 187 3.17 技巧31:记住,并不是所有程序都是用C编写的 190 3.18 技巧32:理解缓冲区长度带来的影响 195 第4章 工具和资源 199 4.1 技巧33:熟悉ping实用工具 199 4.2 技巧34:学习使用tcpdump或类似的工具 201 4.2.1 tcpdump是如何工作的 202 4.2.2 使用tcpdump 205 4.2.3 tcpdump的输出 206 4.2.4 小结 210 4.3 技巧35:学习使用traceroute 210 4.3.1 traceroute是如何工作的 212 4.3.2 Windows TRACERT 214 4.3.3 小结 215 4.4 技巧36:学习使用ttcp 215 4.5 技巧37:学习使用lsof 219 4.6 技巧38:学习使用netstat 221 4.6.1 活动套接字 221 4.6.2 接口 223 4.6.3 路由表 223 4.6.4 协议统计 225 4.6.5 Windows版的netstat 227 4.6.6 小结 227 4.7 技巧39:学习使用系统中的调用追踪工具 227 4.7.1 过早终止 227 4.7.2 ttcp性能问题 231 4.7.3 小结 232 4.8 技巧40:构建并使用捕获ICMP报文的工具 233 4.8.1 读取ICMP报文 233 4.8.2 打印ICMP报文 234 4.8.3 小结 239 4.9 技巧41:读Stevens的书 240 4.9.1 《TCP/IP详解》丛书 240 4.9.2 《UNIX网络编程》丛书 241 4.10 技巧42:阅读代码 242 4.11 技巧43:访问RFC编辑者的页面 243 4.12 技巧44:经常访问新闻组 244 附录A 各种UNIX代码 247 附录B 各种Windows代码 250 参考书目 253 索引 257 ======================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值