TCP也叫传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。
面向连接
✦ TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
✦ 在通信开始之前,先建立相关的链接,才能发送数据,类似于生活中,"打电话"。
✦ 完成数据交换后,双方必须断开此连接,以释放系统资源。
✦ 这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。
✦ TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功
✦ 发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。
✦ TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
✦ TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。
TCP通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话"
比如一个人想打10086求助人工服务。 tcp的客户端要比服务器端简单很多,客户端只需要找一个电话亭,拿起电话拨打即可。
示例代码:
from socket import *
# 创建socket
tcp_client_socket = socket(AF_INET, SOCK_STREAM)
# 目的信息
server_ip = input("请输入服务器ip:")
server_port = int(input("请输入服务器port:"))
# 链接服务器
tcp_client_socket.connect((server_ip, server_port))
# 提示用户输入数据
send_data = input("请输入要发送的数据:")
tcp_client_socket.send(send_data.encode("gbk"))
# 接收对方发送过来的数据,最大接收1024个字节
recvData = tcp_client_socket.recv(1024)
print('接收到的数据为:', recvData.decode('gbk'))
# 关闭套接字
tcp_client_socket.close()
在程序中,要完成一个tcp服务器的功能,需要的流程如下:
示例代码:
from socket import *
# 创建socket
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
# 本地信息
address = ('', 7788)
# 绑定
tcp_server_socket.bind(address)
# 使用socket创建的套接字
tcp_server_socket.listen(128)
# 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
client_socket, clientAddr = tcp_server_socket.accept()
# 接收对方发送过来的数据
recv_data = client_socket.recv(1024)
print('接收到的数据为:', recv_data.decode('gbk'))
# 发送一些数据到客户端
client_socket.send("thank you !".encode('gbk'))
# 关闭为这个客户端服务的套接字
client_socket.close()
SYN
请求建立连接字段:1表示与对方要进行网络连接建立 ,0 表示默认没有连接建立请求。
ACK
确认控制字段:1表示上一次发送的数据对方接收了,0 表示没有接收到上次发送的数据信息。
seq
随机序列号。
FIN
请求断开连接字段:1表示与对方断开网络连接,0 表示默认没有断开连接请求。
ack
随机序号回复(ack=seq+1)。
ctl
控制字段号。
TCP十一种状态转移总结 | |||
---|---|---|---|
出现方式 | 出现环境 | 状态名称 | 状态描述 |
TCP建立过程 | 服务端/客户端 | CLOSED | 默认初始化状态 |
服务端 | LISTEN | 建立socket,进入监听状态 | |
客户端 | SYN_SENT | 发送syn报文,进入syn发送状态 | |
服务端 | SYN_RCVD | 接受syn报文,并回复ack及syn报文 | |
服务端/客户端 | ESTABLISHED | 接受syn报文,回复ack建立连接(客户端)接受ack报文,建立连接(服务端) | |
TCP断开过程 | 服务端/客户端 | ESTABLISHED | 默认断开前初始化状态 |
客户端 | FIN_WAIT1 | 发送断开请求FIN报文 | |
服务端 | CLOSE_WAIT | 收到FIN后向客户端发送ACK | |
客户端 | FIN_WAIT2 | 收到服务端返回的ACK报文,等待数据传输。 | |
服务端 | LAST_ACK | 发送FIN断开请求报文 | |
客户端 | TIME_WAIT | 回复FIN断开请求,发送ack报文 | |
服务端/客户端 | CLOSED | 收到ack报文立即转换为断开状态,等待2MSL后,转变为断开状态 | |
客户端 | CLOSEING | 没有收到回复FIN报文的ACK,直接收到FIN |
TCP/IP协议簇之间的关系
TCP/IP协议传输示意图