第 64章 TCP
传输控制协议(tcp,transmission control protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。tcp 是互联网的核心协议之一,通常用于传输数据量较大的数据流。tcp 提供了错误检查、拥塞控制、数据重传和流量控制等功能,确保数据在网络中可靠地传输。
tcp(传输控制协议)和 udp(用户数据报协议)都是互联网协议组(tcp/ip)中的传输层协议,但它们之间存在一些关键区别:
1 可靠性:tcp 是一种可靠的传输协议,它保证数据在传输过程中的完整性和顺序。如果数据包在传输过程中丢失或损坏,tcp 会重新发送丢失的数据包。而 udp 是一种不可靠的传输协议,它不保证数据的可靠性,没有错误检查和纠正机制。
2 连接导向性:tcp 是面向连接的协议,通信双方在建立连接之前不能传输数据。连接建立后,双方可以按顺序发送和接收数据。而 udp 是无连接的协议,通信双方不需要建立连接即可发送数据。
3 传输速度:由于 tcp 的可靠性和拥塞控制机制,其传输速度相对较慢。udp 由于缺乏这些特性,传输速度通常较快,适用于对实时性要求较高的应用。
4 拥塞控制:tcp 具有拥塞控制机制,能够在网络拥塞时调整发送速率,以减轻网络负担。而 udp 没有拥塞控制功能,因此在网络拥塞时可能导致数据包丢失。
5 头部开销:tcp 头部开销较大,约为 20 至 60 字节,具体取决于选项设置。udp 头部开销较小,仅为 8 字节。
6 一对一、一对多通信:tcp 仅支持一对一的通信模式,即一个发送方与一个接收方之间的通信。而 udp 支持一对一、一对多、多对一和多对多的通信模式。
7 适用场景:tcp 适用于对可靠性要求较高、传输数据量大且要求有序的场景,如文件传输、电子邮件和 web 浏览等。udp 适用于对实时性要求较高、可以容忍少量数据丢失的场景,如在线视频、语音通话和实时游戏等。
除了前面提到的可靠性、连接导向性、传输速度、拥塞控制、头部开销和适用场景等方面的区别,tcp 和 udp 在以下方面也存在差异:
1 错误检测与处理:tcp 具有错误检测功能,通过检查数据包中的校验盒来检测错误。如果检测到错误,tcp 会要求重发损坏的数据包。而 udp 没有内置的错误检测功能,因此不能自动检测和修复数据包错误。
2 有序性:tcp 保证数据包的顺序传输,接收方会根据序列号对数据包进行排序。而 udp 不保证数据包的顺序,接收方收到数据包的顺序可能与发送方的顺序不同。
3 数据边界:tcp 是基于字节流的传输协议,没有固定的数据边界。应用层需要通过某种方式定义数据边界,例如使用特定的分隔符。而 udp 是基于数据包的传输协议,每个 udp 数据报都有固定的长度,接收方可以根据数据报的长度来确定数据的边界。
4 流量控制:tcp 使用滑动窗口机制进行流量控制,防止发送方过快地发送数据,导致接收方无法处理。而 udp 没有内置的流量控制功能,因此在高速网络中,发送方可能会过快地发送数据,导致接收方无法及时处理。
5 延迟与实时性:由于 tcp 具有拥塞控制、错误检测和纠正等机制,其传输延迟相对较高。而 udp 由于缺乏这些特性,传输延迟较低,更适合实时应用。
6 头部大小:tcp 头部最小长度为 20 字节,最大长度为 60 字节,具体取决于选项设置。而 udp 头部大小固定为 8 字节。
7 连接状态:tcp 是一种有状态的协议,通信双方需要在数据传输过程中维护连接状态。而 udp 是无状态的协议,通信双方不需要维护连接状态。
根据这些区别,开发者可以在需要可靠数据传输、有序数据传输和有状态连接的场景中选择 tcp,而在对实时性要求较高、可以容忍少量数据丢失的场景中选择 udp。这是一个简单的 python 示例,使用 `socket` 库实现了一个基本的 tcp 客户端和服务器。服务器监听客户端的连接请求,接收客户端发送的消息并原样返回。
服务器端代码(serverpy):
```python
import socket
def main():
server_socket = socketsocket(socketaf_i, socketsock_stream)
server_socketbind((&39;&39;, 12345))
server_socketlisten(1)
print(&34;服务器已启动,等待客户端连接&34;)
while true:
client_socket, client_address = server_socketaccept()
print(f&34;客户端 {client_address} 已连接&34;)
while true:
data = client_socketrecv(1024)
if not data:
break
print(f&34;收到客户端消息: {datadecode()}&34;)
client_socketsendall(data)
client_socketclose()
print(f&34;客户端 {client_address} 已断开连接&34;)
if __name__ == &34;__main__&34;:
main()
```
客户端代码(clientpy):
```python
import socket
def main():
client_socket = socketsocket(socketaf_i, socketsock_stream)
client_socketconnect((&39;&39;, 12345))
while true:
message = input(&34;请输入要发送的消息:&34;)
if not message:
break
client_socketsendall(messageencode())
data = client_socketrecv(1024)
print(f&34;收到服务器消息: {datadecode()}&34;)
client_socketclose()
print(&34;客户端已断开连接&34;)
if __name__ == &34;__main__&34;:
main()
```
首先,运行服务器端代码(serverpy):
```
python serverpy
```
然后,运行客户端代码(clientpy):
```
python clientpy
```
客户端和服务器建立连接后,客户端可以输入并发送消息,服务器会原样返回收到的消息。当客户端输入空消息时,客户端和服务器将断开连接。
这个示例展示了如何使用 python 的 `socket` 库实现一个简单的 tcp 通信。
以下是使用 nodejs 的 `` 模块实现的简单 tcp 通信示例,包括一个服务器和一个客户端。客户端向服务器发送消息,服务器原样返回收到的消息。
服务器端代码(serverjs):
```javascript
const = require(&39;&39;);
const server = createserver((socket) => {
consolelog(&39;客户端已连接&39;);
socketon(&39;data&39;, (data) => {
consolelog(`收到客户端消息: {datatostring()}`);
socketwrite(data);
});
socketon(&39;end&39;, () => {
consolelog(&39;客户端已断开连接&39;);
});
});
serverlisten(12345, () => {
consolelog(&39;服务器已启动,等待客户端连接&39;);
});
```
客户端代码(clientjs):
```javascript
const = require(&39;&39;);
const client = createconnection({ port: 12345 }, () => {
consolelog(&39;已连接服务器&39;);
const message = &39;你好,服务器!&39;;
clientwrite(message);
clienton(&39;data&39;, (data) => {
consolelog(`收到服务器消息: {datatostring()}`);
});
clienton(&39;end&39;, () => {
consolelog(&39;与服务器断开连接&39;);
});
});
clienton(&39;error&39;, (error) => {
consoleerror(`发生错误: {error}`);
});
```
首先,运行服务器端代码(serverjs):
```
node serverjs
```
然后,运行客户端代码(clientjs):
```
node clientjs
```
客户端和服务器建立连接后,客户端可以输入并发送消息,服务器会原样返回收到的消息。当客户端输入空消息时,客户端和服务器将断开连接。
这个示例展示了如何使用 nodejs 的 `` 模块实现一个简单的 tcp 通信。