Python socket之TCP通信及下载文件的实现

  • Post category:Python

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模块。