TCP(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
创建TCP通信三个步骤:
- 创建连接
- 数据传送
- 终止连接
TCP通信类似于生活中的打电话,通信开始前一定要先建立相关的连接。
TCP特点:
- 面向连接 这种连接是一对一的,因此TCP不适用于广播的应用程序
- 可靠传输
- TCP采用应答机制
- 超时重传
- 错误校验
- 流量控制和阻塞管理
TCP优点:
- 可靠、稳定
- 适合传输大量数据
TCP缺点:
- 传输速度慢
- 占用系统资源高
TCP的使用场景:对网络通讯质量有较高要求
- 浏览器 HTTP协议基于TCP协议
- 文件传输
TCP的三次握手(连接)
TCP的4次挥手(断开)
TCP网络程序流程
案例 基于TCP的文件下载器(同步下载)
TCP严格区分客户端与服务端。
TCP客户端
import socket
if __name__ == '__main__':
# 创建tcp客户端套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 和服务端程序建立连接
tcp_client_socket.connect(("127.0.0.1", 8989))
# 接收用户下载的文件名数据
file_name = input("请输入您要下载的文件名:")
# 对字符串进程编码成为二进制数据
file_name_data = file_name.encode("utf-8")
# 发送数据
tcp_client_socket.send(file_name_data)
# 指定路径,先把文件创建到指定路径,然后在打开文件写入数据
with open("/home/python/Desktop/" + file_name, "wb") as file:
# 循环接收服务端发送的文件二进制数据
while True:
# 接收一次服务端发送的数据
file_data = tcp_client_socket.recv(1024)
if file_data:
# 循环往文件中写入数据
file.write(file_data)
else:
# 服务端发送文件完成
break
# 关闭套接字
tcp_client_socket.close()
TCP服务端
import socket
import os
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置socket选项,程序退出端口号立即释放, 可以复用端口号
# 提示: 默认是 tcp断开连接,但真正释放端口号需要等待1-2分钟
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True)
# 给程序绑定端口号
tcp_server_socket.bind(("", 8989))
# 设置监听
tcp_server_socket.listen(128)
# 循环等待接收客户端的连接请求,可以服务与多个客户端, 但是是一个客户端下载文件以后另外一个客户端才能下载文件
while True:
# 等待接收客户端的连接请求
service_client_socket, ip_port = tcp_server_socket.accept()
# 代码执行到此,说明连接建立成功
print("客户端的ip地址和端口号:", ip_port)
# 接收客户端请求数据(其实就是客户端发送的文件名)
recv_data = service_client_socket.recv(1024)
# 对二进制数据进行解码
file_name = recv_data.decode("utf-8")
print(file_name)
# 判断请求的文件是否存在
# 1. try-except 如果打开文件出现异常,说明文件不存在
# 2. os.path.exits 判断文件是否存在
# 判断指定文件或者文件夹是否存在
if os.path.exists(file_name):
# 根据客户端请求文件名打开指定文件,读取文件中的数据
with open(file_name, "rb") as file:
while True:
# 读取文件数据
file_data = file.read(1024)
if file_data:
# 发送数据给客户端
service_client_socket.send(file_data)
else:
# 文件读取完成
break
else:
service_client_socket.send("无此文件".encode("utf-8")
service_client_socket.close()
# tcp_server_socket.close()
TCP注意点:
- tcp服务器一般情况下都需要绑定端口号,否则客户端找不到这个服务器
- tcp客户端一般不绑定端口号,使用随机生成的端口号即可
- 当一个tcp客户端和服务端连接成功后,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
- listen后的套接字是被动套接字,只用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
- 关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够连接服务器,但是之前已经连接成功的客户端正常通信
- 关闭accept返回的套接字意味着这个客户端已经服务完毕,注意和第5点的区别
- 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线
2.TCP和UDP的区别
- TCP面向连接,UDP不面向连接
- TCP需要连接 传输速度慢,UDP不需要连接 传输速度快
- TCP不支持发广播,UDP支持发广播
- TCP对系统资源要求较多,UDP对系统资源要求较少
- TCP提供可靠的数据传输,UDP不保证可靠的数据传输,易出现丢包情况
- TCP适合发送大量数据,UDP适合发送少量数据
- TCP有流量控制,UDP没有流量控制