TCP/IP高效编程:改善网络程序的44个技巧
- TCP的ACK窗口:说明接下来期望接受到的序列号
- 发送窗口:
- 已发送但还未ACK的
- 可以发送但还未发送的(发送这部分的数据包无需ACK,但是会启动一个RT(重传计时)。。。)
- p20 代理ARP:同网段的机器知道另一个网段的机器物理地址,并假装自己就是其物理地址(这个技术应该早落伍了吧?)
- 看起来像是Windows里的透明代理?
- A,B,C 3类 --> 子网划分(B、C网段太大)--> CIDR
- NAT
- Socket API比XTI/TLI更好用(后面的是什么东西?)2者只是不同的编程接口,底层都是基于TCP/IP的
- readn readvrec ???
- 不要低估TCP的性能
- 主要CPU处理都在数据复制和校验
- Jacobson描述了一个实验TCP,正常接受只有30条RISC指令长(?!)
- RFC 1122:建议延迟发送ACK,最大不超过0.5s,并每2个全尺寸段至少一个ACK
- 3次握手:SYN --> SYN+ACK --> Data+ACK(如何防止中间网关的恶意破坏连接???)
- 评论:TCP测吞吐量(带宽),UDP测延迟
- 本地主机时,最大段长度可以到16384(!),使得性能提高
- RFC T/TCP:免除连接建立3次握手,并缩短关闭时的TIME-WAIT——没有得到广泛应用
- TCP/IP不是轮询的
- 如果应用程序不发送数据,它可能永远都不会发现连接丢失
- SO_KEEPALIVE:。。。一个问题是它不仅检测了死连接,也丢失了这些连接,应用程序可能不希望如此(!)
- 应用程序自己实现‘MSG_HEARTBEAT’
- 检测无效输入(这一点即使是现在都做得不好,一些随机数据测试就能导致网络应用程序崩溃!)
- readline(fd,buff,len)的正确实现
- LAN上运行良好的可能在WAN上出问题
- 了解网络底层协议是如何工作的(如Nagle算法)
- 不要太把OSI 7层模型当回事
- 它受到‘通信思维’的影响,更适用于电话系统而不是计算机系统
- TCP角度看写操作
- 任意时刻能够发送的最大数据量是min(发送窗口,拥塞窗口)
- 慢启动:从1开始,先2倍增加直到门限,然后‘拥塞避免’线性增加(by 1?)
- Nagle:任意时刻,未被确认的‘小’段(长度<MSS)不能够超过一个
- 理解TCP的有序释放
- shutdown(s,2); 等价于close/closesocket,——实际上不一样,shutdown导致持有者无法读写,但调用close后其他持有者仍然能。。。
- 应用程序发送一个EOF状态(数据包无数据负荷?):select收到通知,但无数据可读
- inetd
- 等待标记???nowait相当于支持客户端并发连接
- 用tcpmux分配端口?(一个本地端口转发服务?)——但这么做不安全。。
- *考虑使用2条TCP连接(应用级别的双向读写?)
- *使应用程序成为Event Driven的
- tselect
- 不要用TIME-WAIT暗杀来关闭一条连接
- SO_LINGER?
- 服务器应该设置SO_REUESEADDR
- 可能的话,使用一个大规模的write
- 禁用Nagle:TCP_NODELAY=1
- 合并写操作:writev/readv
- 理解如何使connect超时
- 没收到SYN的ACK之前(一个RTT,def=75s),connect是不会返回的
- 有问题的方法:signal( SIGALRM , )
- 第2种方法:使用无阻塞的connect,用select等待它完成——存在可移植性问题
- fcntl(s, F_SETFL, flags | O_NONBLOCK ); ...
- *避免数据复制
- 共享内存缓冲区:#include "etcp.h"?shm/CreateFileMapping
- 使用前将sockaddr_in清零(sin_zero域)
- 注意字节顺序
- p184 2000年的时候就已经有IPv6应用了???靠
- 对UDP使用connect:为了收到异步错误通知?否则ICMP无法匹配哪个UDP
- p198 至少应该将send buffer设置为3倍MSS?
- 工具:ping tcpdump traceroute ttcp lsof netstat ktrace/truss/strace