传输控制协议TCP,建立在网际层协议提供的数据包传输技术之上
程序间使用连续的数据流进行相互通信,除非网络原因导致通信中断
用于传输文档与文件
人机长对话的协议的基础之一
数据包被隐藏在协议层之下:流数据
可靠连接
TCP包提供序列号,数据包排序。要求重传丢失的数据包
用计数器记录发送的字节数。网络栈无需记录数据流分割的方式。
初始序列号随机选择
不以锁步的方式进行通信。发送多个数据包(传输量称TCP窗口)无需等待响应
接收方TCP控制发送方TCP窗口,减缓、暂停连接:流量控制
缓冲区满时,禁止更多传输,对到达的数据丢弃
TCP认为数据包被丢弃——假定网络拥挤——减少发送的数据量
客户端只需发送单个较小的请求,请求完成后无后续通信:UDP
两台主机间建立连接需要三个数据包
SYN SYN-ACK ACK
不存在长连接时,不必TCP(开销)。客户端太多时,单独保存数据流内存占用大。
有比简单重传更聪明的方案
3.3TCP套接字含义
端口号:与UDP方案一致
connect
UDP:连接概念只带来操作的便利性
TCP:支持状态的流协议
connect调用必须是首要步骤。后续所有网络通信的必要条件。
可能失败,持续的连接
要求另一方做好接受连接的准备,处于监听状态
服务器不进行connect调用(connect是主动行为)。接收连接请求,新建一个套接字
TCP标准的POSIX接口包含了两种套接字:
被动套接字,监听套接字。不发送接收数据,不表示实际网路会话,用于告知OS使用端口号接受连接请求?
主动套接字,连接套接字。只用于与特定的主机通信
就像Unix的文件或管道
被动socket:二元组
主动socket:四元组
UDP接受的只可能是完整的数据包
TCP数据流分为多个数据包,接收端重组
发送成功:网卡空闲,或发送缓冲区未满
发送暂停:网卡正忙,或发送缓冲区已满。send阻塞进程
发送一半:缓冲区不够,部分传输。send返回接收的字节数
调用send需检查返回值
在循环内调用
部分传输时,不断尝试发送剩余数据
sendall(c实现)
循环中释放了全局解释器锁,其他python线程在所用数据传输完之前不会竞争资源
同理,循环调用recv
信息长度不定,没有recvall
可在部分数据到达时开始读取并处理
读到Content_length头后知道
每个会话使用一个套接字
监听套接字
连接套接字
bind简单声明用于本程序的端口
listen:套接字用于监听
调用accpet接受连接请求
调用后等待新客户端连接服务器,返回一个全新的套接字(负责管理对应的新建会话)
getsockname:正在使用的绑定TCP端口
getpeername(=accept第二返回值)对应的客户端地址
close()关闭套接字
网络栈谨慎处理连接的关闭
监听套接字:立即关闭,被操作系统忽略
通信的连接套接字:不能确定最后的数据包被对方接收
套接字选项:SO_REUSEADDR
能够使用连接正在关闭的端口
3.5绑定接口
成功连接另一台主机
3.6死锁
两个程序共享有限资源
一直等待对方结束资源占用
TCp栈中有缓存区,暂时保持数据
如果协议没有严格要求 服务器在客户端请求发送完成后才 读取完整请求 然后返回完整响应
可能阻塞(死锁)
套接字对象在遇到文件结束符时处理方法:
py文件对象:空字符串
socket关闭:空字符串
套接字半关:一个方向上永久关闭通信连接,但不销毁套接字
服务器不读取数据,发送剩余响应
shutdown调用
SHUT_WR不再想套接字写入数据
SHUT_RDWR
close()只结束了调用他的进程与套接字的关系,套接字对其他进程可用
SHUTDOWN()对所有进程不可用
socket对象,调用makefile,返回python文件对象,read,write(底层调用send,recv)
fileno方法,获取文件描述符编号