目录
1.什么是TCP?
1.1 TCP概念
TCP:英文全拼(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议.。
TCP通信模型中,在通信开始之前,一定要先建立相关的连接,才能发送数据,类似于生活中的"打电话"。
1.2 TCP的优缺点
优点:稳定,可靠,适合传输大量数据;
缺点:传输速度慢,占用系统资源高
1.3 TCP的使用场景
对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。在日常生活中,常见使用TCP协议的应用:浏览器,QQ文件传输
1.4 TCP需要注意的点
tcp服务器一般情况下都需要绑定端口号,否则客户端找不到这个服务器
tcp客户端一般不绑定端口号,使用随机生成的端口号即可
tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
当一个tcp客户端和服务端连接成功后,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务,如图:
listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
关闭accept返回的套接字意味着这个客户端已经服务完毕
2.客户端
客户端要做的事:和服务端建立连接→向服务端发送文件下载请求→接收服务端数据并保存→接收完成关闭连接
import socket
if __name__ == '__main__':
# 创建套接字,AF_INET:ipv4,SOCK_STREAM:TCP协议
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 和服务端连接
tcp_client_socket.connect(("服务端的ip", 端口号))
# 发送下载文件的请求
file_name = input("请输入要下载的文件名:")
# 个人在服务端和客户端都采用utf-8编码
file_name_data = file_name.encode("utf-8")
# 发送请求数据
tcp_client_socket.send(file_name_data)
# 把数据写入到文件里
with open("文件下载位置,我放到了桌面:C:/Users/*/Desktop/" + file_name, "wb") as file:
while True:
# 循环接收文件数据
file_data = tcp_client_socket.recv(1024)
# 只要接收到数据,就写入
if file_data:
file.write(file_data)
else:
print("服务端把数据发送完成并关闭了连接")
break
# 关闭套接字
tcp_client_socket.close()
3.服务端
服务端要做的事:绑定端口号→等待客户端的连接请求→接收客户端的下载文件请求→判断数据是否存在→读取数据→把数据发送给客户端
import socket
import os
if __name__ == '__main__':
# 在这里我将os.path的默认路径进行了更改,改到了桌面
os.chdir("/home/python/Desktop")
# 创建tcp服务端套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定端口号,ip地址不绑定
tcp_server_socket.bind(("", 3356))
# 程序结束,释放端口号,端口号复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 设置监听,把主动套接字变成被动套接字,服务端套接字只负责接收客户端的连接请求
tcp_server_socket.listen(128)
while True:
# 创建信的套接字,等待接收客户端的连接请求
service_client_socket, ip_port = tcp_server_socket.accept()
print("客户端连接成功了:", ip_port)
# 接收客户端的请求信息
file_name_data = service_client_socket.recv(1024)
# 对二进制数据进行解码
file_name = file_name_data.decode("utf-8")
# 判断文件是否存在
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:
print("请求的文件数据发送完成")
break
else:
print("您请求下载的文件不存在")
# 终止和这个客户端服务
service_client_socket.close()
# 终止客户端连接请求服务, 服务端的套接字可以不用关闭
tcp_server_socket.close()
4.运行效果
①在服务器端创建文件kk.txt,如图:
②先打开服务器
③打开客户端
同时,服务器显示连接成功:
④输入kk.txt
⑤传输结果