Python socket之TCP通信及下载文件的实现
什么是Python socket?
Python的socket模块提供了一种方便的方式来进行网络编程。通过Python中的socket,我们可以构建面向连接和无连接的网络程序。
TCP协议
TCP协议是基于连接的、可靠的传输协议,数据传输前要先建立连接。TCP协议的数据传输是有顺序的、不会丢失、不会重复,数据传输效率较低。
TCP通信的实现
在Python的socket模块中,通过socket.socket()
方法创建socket对象,可以完成TCP通信的实现。其中,socket对象的参数有:
- socket.AF_INET:IPv4网络协议
- socket.SOCK_STREAM:TCP传输协议
接下来,通过示例讲解TCP通信的实现。
示例一:服务端和客户端的简单交互
服务端代码:
import socket
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind(('localhost', 8000))
server_sock.listen(5)
while True:
client_sock, addr = server_sock.accept()
print('Connection from:', addr)
while True:
data = client_sock.recv(1024)
if not data:
break
client_sock.sendall(data)
client_sock.close()
客户端代码:
import socket
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect(('localhost', 8000))
client_sock.sendall(b'Hello, world')
data = client_sock.recv(1024)
client_sock.close()
print('Received:', repr(data))
服务端代码中,通过socket.bind()
方法指定IP地址和端口号,并使用socket.listen()
方法监听客户端连接请求。当服务端接收到客户端的连接请求后,通过socket.accept()
方法接收客户端连接,返回客户端socket和地址。然后,服务端通过socket.recv()
方法接收客户端发送过来的数据,并通过socket.sendall()
方法把数据返回给客户端。
客户端代码中,通过socket.connect()
方法连接服务端,并通过socket.sendall()
方法将数据发送给服务端。然后,通过socket.recv()
方法接收服务端返回的数据。
示例二:TCP文件下载
服务端代码:
import os
import socket
CHUNK_SIZE = 1024 * 1024 # 每次读取 1MB 数据
def send_file(conn, filepath):
filesize = os.path.getsize(filepath)
conn.send(str(filesize).encode()) # 发送文件大小
with open(filepath, 'rb') as f:
while True:
data = f.read(CHUNK_SIZE)
if not data:
break
conn.send(data)
print('File sent.')
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind(('localhost', 8000))
server_sock.listen(1)
while True:
conn, addr = server_sock.accept()
print('Connection from:', addr)
file_path = '/path/to/file'
send_file(conn, file_path)
conn.close()
客户端代码:
import os
import socket
CHUNK_SIZE = 1024 * 1024 # 每次读取 1MB 数据
def receive_file(conn, filepath):
filesize = int(conn.recv(1024).decode()) # 接收文件大小
with open(filepath, 'wb') as f:
while filesize:
if filesize >= CHUNK_SIZE:
data = conn.recv(CHUNK_SIZE)
filesize -= CHUNK_SIZE
else:
data = conn.recv(filesize)
filesize = 0
f.write(data)
print('File received.')
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect(('localhost', 8000))
file_path = '/path/to/save/file'
receive_file(client_sock, file_path)
client_sock.close()
服务端代码通过send_file()
方法将本地文件发送给客户端。其中,通过os.path.getsize()
方法获取文件大小,并通过socket发送文件大小。然后,通过open()
方法打开本地文件,每次读取1MB数据,并通过socket将数据发送给客户端。
客户端代码通过receive_file()
方法从服务端接收文件。其中,通过socket.recv()
方法接收服务端发送过来的文件大小,并将文件大小转换成整数;再通过open()
方法打开本地文件,并按照获取的文件大小逐次接收数据,并将接收的数据写入本地文件中。
总结
Python socket在TCP通信和文件传输中有着广泛的应用。通过学习TCP通信的实现和文件传输的实现,我们可以更好地理解Python的socket模块。