Python基于SocketServer实现轻量级文件传输服务器与客户端
本文提供基于Python标准库开发的轻量级TCP文件传输服务器与客户端方案。服务端利用SocketServer实现多线程并发处理,内置姓名与密码校验逻辑,并通过分块读取与EOF标志确保文件稳定传输;客户端负责交互式认证、进度等待及本地文件落盘。适用于局域网内快速部署测试或学习网络通信基础原理。
运行环境与核心逻辑说明
该方案完全依赖Python内置网络库,无需安装任何第三方依赖。服务端采用SocketServer模块提供的多线程能力,为每个客户端连接分配独立线程执行任务;客户端通过标准TCP Socket建立握手,并在传输前完成身份核验。整个流程围绕认证、分块读写与状态同步展开,适合初学者理解点对点文件交换的核心机制。
第1步:配置服务端基础框架
目的:初始化多线程TCP监听,定义请求处理类并接管连接生命周期。
入口与参数:脚本顶层运行,绑定地址 localhost 与端口 50000。用户凭证以静态字典管理,实际项目中建议替换为数据库或环境变量。
import SocketServer, time
class MyServer(SocketServer.BaseRequestHandler):
userInfo = {
'yangsq' : 'yangsq',
'hudeyong' : 'hudeyong',
'mudan' : 'mudan' }
def handle(self):
print 'Connected from', self.client_address
while True:
receivedData = self.request.recv(8192)
if not receivedData:
continue
elif receivedData == 'Hi, server':
self.request.sendall('hi, client')
elif receivedData.startswith('name'):
self.clientName = receivedData.split(':')[-1]
if MyServer.userInfo.has_key(self.clientName):
self.request.sendall('valid')
else:
self.request.sendall('invalid')
elif receivedData.startswith('pwd'):
self.clientPwd = receivedData.split(':')[-1]
if self.clientPwd == MyServer.userInfo[self.clientName]:
self.request.sendall('valid')
time.sleep(5)
sfile = open('PyNet.pdf', 'rb')
while True:
data = sfile.read(1024)
if not data:
break
while len(data) > 0:
intSent = self.request.send(data)
data = data[intSent:]
time.sleep(3)
self.request.sendall('EOF')
else:
self.request.sendall('invalid')
elif receivedData == 'bye':
break
self.request.close()
print 'Disconnected from', self.client_address
print
if __name__ == '__main__':
print 'Server is started\nwaiting for connection...\n'
srv = SocketServer.ThreadingTCPServer(('localhost', 50000), MyServer)
srv.serve_forever()
第2步:编写客户端认证与接收逻辑
目的:建立TCP连接,按顺序发送问候、用户名与密码,待服务端校验通过后拉取文件并写入本地磁盘。
重要参数:目标端口 50000,接收缓冲区 1024 字节,结束标识 "EOF"。
import socket, time
class MyClient:
def __init__(self):
print 'Prepare for connecting...'
def connect(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 50000))
sock.sendall('Hi, server')
self.response = sock.recv(8192)
print 'Server:', self.response
self.s = raw_input("Server: Do you want get the 'thinking in python' file?(y/n):")
if self.s == 'y':
while True:
self.name = raw_input('Server: input our name:')
sock.sendall('name:' + self.name.strip())
self.response = sock.recv(8192)
if self.response == 'valid':
break
else:
print 'Server: Invalid username'
while True:
self.pwd = raw_input('Server: input our password:')
sock.sendall('pwd:' + self.pwd.strip())
self.response = sock.recv(8192)
if self.response == 'valid':
print 'please wait...'
f = open('b.pdf', 'wb')
while True:
data = sock.recv(1024)
if data == 'EOF':
break
f.write(data)
f.flush()
f.close()
print 'download finished'
break
else:
print 'Server: Invalid password'
sock.sendall('bye')
sock.close()
print 'Disconnected'
if __name__ == '__main__':
client = MyClient()
client.connect()
第3步:启动双端程序进行传输测试
操作顺序:先执行服务端脚本确认 warming for connection... 提示,再运行客户端。当客户端输入 y 后,依次键入已注册的名称与对应密码。服务端控制台会打印连接日志与发送状态,客户端收到 valid 后会暂停约5秒用于服务端预热与分块发送,完成后在终端打印 download finished 并自动关闭连接。
完成判断:本地生成 b.pdf 文件,且两端控制台均显示断开日志即表示传输闭环成功。
关键实现细节与维护建议
流式分块与粘包处理:服务端未直接使用一次性 sendall,而是循环读取 1024 字节并逐段发送,剩余未发数据保留在下一次循环中。这种写法能有效应对内核缓冲区满导致的阻塞问题。
状态同步机制:采用自定义文本协议(Hi, server、name:、pwd:、EOF)作为控制指令。客户端依据 EOF 字符串截断循环,避免无限期阻塞等待。
备份与风险提示:客户端覆盖模式打开 b.pdf,若本地已存在同名文件将被静默覆盖。重要场景建议在写入前添加哈希校验或文件名时间戳防冲突。此外,明文传输密码与文件内容仅适用于内部测试网,对外服务必须升级至 TLS 加密通道并引入速率限制。
以上就是 Python 基于 SocketServer 实现简单文件传输服务器与客户端的详细内容,更多关于 TCP 网络编程与标准库实战的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









