TCP 的特性
- TCP 提供一种面向连接的、可靠的字节流服务
- 在一个 TCP 连接中,仅有两方法进行彼此通信。广播和多播不能用于 TCP。
- TCP 使用校验和,确认和重传机制来保证可靠传输
- TCP 给数据分节进行排序,并使用累计确认保证数据的顺序不变和非重复
- TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
TCP 和 UDP 的区别
协议 | 连接性 | 双工性 | 可靠性 | 有序性 | 有界性 | 拥塞控制 | 传输速度 | 量级 | 头部大小 |
---|---|---|---|---|---|---|---|---|---|
TCP | 面向连接 | 全双工 (1:1) | 可靠(重传机制) | 有序(通过SYN排序) | 无,有粘包情况 | 有 | 慢 | 低 | 20~60字节 |
UDP | 无连接 | n:m | 不可靠(丢包后数据丢失) | 无序 | 有消息边界,无粘包 | 无 | 快 | 高 | 8字节 |
TCP 粘包是什么,如何处理
默认情况下,TCP 连接会启用延迟算法(Nagle 算法),在数据发送之前缓存他们,如果短时间有多个数据发送,会缓冲到一起作一次发送,以此减少 IO 消耗提高性能
如果是传输文件的话,不需要处理粘包问题,来一个拼一个包即可。但是如果还是多条消息,或者别的用途的数据就需要处理粘包。
常见的解决方案有:1)多次发送之前间隔一个等待时间;2)关闭 Nagle 算法;3)进行封包/拆包
为什么 UDP 不会粘包
- TCP 是面向流的协议,UDP 是面向消息的协议
UDP 段是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据 - UDP 具有保护消息边界,在每个 UDP 包中就有了消息头(来源地址,端口等信息),对于接收端来说就容易进行区分处理。传输协议把数据当做一条独立的消息在网上传输,接收端只能接收独立的消息。接收端一次只能接收发送端发出的一个数据包,如果一次接受数据的大小小于发送端一次发送的数据大小,就会丢失一部分数据,即使丢失,接收端也不会分两次去接收。
常用端口与对应的服务
端口 | 作用说明 |
---|---|
21 | 主要用于 FTP(File Transfer Protocol)服务 |
23 | 主要用于 Telnet(远程登录)服务,是 Internet 上普遍采用的登录和仿真程序 |
25 | 为 SMTP(Simple Mail Transfer Protocol)服务器所开放,主要用于发送邮件,如今大多数邮件服务都使用该协议 |
53 | 为 DNS (Domain Name Server)服务器所开放,主要用于域名解析,DNS 服务在 NT 系统中使用地最为广泛 |
67、68 | 分别是为 Bootp 服务的 Bootstrap Protocol Server(引导程序协议服务端)和 Bootstrap Protocol Client(引导程序协议客户端)开放的端口 |
69 | TFTP 是 Cisco 公司开发的一个简单文本传输协议,类似于 FTP |
79 | 为 Finger 服务开放的,主要用于查询远程主机在线用户、操作系统类型以及是否缓冲区溢出等用户的详细信息 |
80 | 为 HTTP 开放,主要用于在 WWW 服务上传输信息的协议 |
99 | 用于一个名为“Metagram Relay”(亚对策延时)服务 |
109、110 | 109 为 POP2(Post Office Protocol Version 2)服务开放,110 为 POP3 服务开放,二者主要用于接收邮件 |
111 | SUN 公司的 RPC(Remote Procedure Call)服务所开放的端口,主要用于分布式系统中不同计算机的内部进程通信,RPC 在多种网络服务中都是很重要的组件 |
113 | 主要用于 Windows 的“Authentication Service”(验证服务) |
119 | 为 “Network News Transfer Protocol”(网络新闻组传输协议,NNTP)开放 |
135 | 主要用于使用 RPC(Remote Procedure Call,远程过程调用)协议,并提供 DCOM (分布式组件对象模型)服务 |
137 | 主要用于“NetBIOS Name Service”服务 |
139 | 为“NetBIOS Session Service”提供的,主要用于提供 Windows 文件和打印机共享以及 Unix 中的 Samba 服务 |
143 | 主要用于“Internet Message Access Protocol V2”(Internet 消息访问协议,简称 IMAP) |
161 | 用于“Simple Network Management Protocol”(简单网络管理协议,简称 SNMP) |
443 | 即网页浏览端口,主要是用于 HTTPS 服务,是提供加密和通过安全端口传输的另一种 HTTP |
554 | 默认情况下用于“Real Time Streaming Protocol”(实时流协议,RTSP) |
1024 | 一般不固定分配给某个服务,Reserved(保留) |
1080 | Socks 代理服务使用的端口 |
1755 | 默认用于“Microsoft Media Server”(微软媒体服务器,MMS) |
4000 | 为 QQ 客户端开放的端口,QQ 服务端使用的端口是 8000 |
5554 | 一种针对微软 Isass 服务的新蠕虫病毒,利用 TCP 5554 端口开启一个 FTP 服务,主要用于病毒的传播 |
5632 | 远程控制软件 pcAnywhere 所开启的端口 |
8080 | 同 80 端口,被用于 WWW 代理服务,可以实现网页 |
OSI 七层模型
TCP 连接建立的三次握手
建立一个 TCP 连接时,需要客户端和服务器总共发送 3 个包。
三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 coonect() 时。将触发三次握手。
- 第一次握手(SYN = 1,seq = x)
客户端发送一个 TCP 的 SYN 标志位为 1 的包,指明客户端打算连接的服务器端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里 - 第二次握手(SYN = 1, ACK = 1,seq = y,ACKnum = x + 1)
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为 1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加 1,即 X + 1。发送完毕后,服务器端进入 SYN_RCVD 状态。 - 第三次握手(ACK = 1, ACKnum = y + 1)
客户端再次发送确认包(ACK),SYN 标志位为 0,ACK 标志位为 1,并且把服务器发来 ACK 的序号字段 +1,放在确认字段中发送给对方,并且在数据段放写 ISN 的 +1。发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。
TCP 连接断开的四次挥手
TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。
- 第一次挥手(FIN = 1, seq = x)
假设客户端想要关闭连接,客户端发送一个 FIN 标志位为 1 的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。发送完毕后,客户端进入 FIN_WAIT_1 状态。 - 第二次挥手(ACK = 1, ACKnum = x + 1)
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后进入 FIN_WAIT_2 状态,等待服务器端关闭连接。 - 第三次挥手(FIN = 1, seq = y)
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为 1。发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个 ACK。 - 第四次挥手(AKC = 1, ACKnum = y + 1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT 状态,等待可能出现的要求重传的 ACK 包。服务器端接收到这个确认后,关闭连接,进入 CLOSED 状态。客户端等待了某个固定时间(两个大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。