客户端代码
import os # 导入操作系统模块,用于文件操作
import struct # 导入struct模块,用于处理字节和数据结构之间的转换
from socket import * # 导入socket模块,用于网络通信
from threading import Thread # 导入线程模块,用于多线程处理
def receive_image(sock):
fileinfo_size = struct.calcsize('128sq') # 计算接收文件名和文件大小的字节大小
buf = sock.recv(fileinfo_size) # 接收图片名
if buf:
filename, filesize = struct.unpack('128sq', buf) # 解析文件名和文件大小
fn = filename.decode().strip('\x00') # 将文件名解码并去掉空字符
new_filename = os.path.join('./', 'client_' + fn) # 在当前目录下构建新文件名
recvd_size = 0
with open(new_filename, 'wb') as fp: # 以二进制写模式打开文件
while recvd_size < filesize:
data = sock.recv(1024) # 接收数据
if not data:
break
fp.write(data) # 写入接收到的数据
recvd_size += len(data) # 统计已接收的数据大小
print('写入完成')
sock.close() # 关闭连接
def send_data():
while True:
msg = input(">") # 接收用户输入的消息
client_socket.send(msg.encode('gbk')) # 发送消息给服务器
if msg == "end":
print("结束发送消息")
break
if __name__ == '__main__':
client_socket = socket(AF_INET, SOCK_STREAM) # 创建客户端套接字对象(IPv4和TCP协议)
client_socket.connect(("127.0.0.1", 6551)) # 连接指定的服务器 IP 地址和端口号
t2 = Thread(target=send_data) # 创建线程,用于发送消息
t2.start() # 启动线程
receive_image(client_socket) # 接收图片数据
t2.join() # 等待线程结束
client_socket.close() # 关闭套接字连接
服务端代码
import os # 导入操作系统模块,用于文件操作
import struct # 导入struct模块,用于处理字节和数据结构之间的转换
from socket import * # 导入socket模块,用于网络通信
from threading import Thread # 导入线程模块,用于多线程处理
def recv_data(client_socket, client_info):
while True:
recv_data = client_socket.recv(1024) # 最大接收1024字节的数据
recv_content = recv_data.decode("gbk") # 解码接收到的消息
print(f"客户端:{recv_content}, 来自:{client_info}")
if recv_content == "图片":
filepath = "new_123.jpg"
fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),
os.stat(filepath).st_size) # 将文件名和文件大小以128sq的格式打包
client_socket.send(fhead) # 发送文件头信息
with open(filepath, 'rb') as fp: # 打开要传输的图片文件
while True:
data = fp.read(1024) # 读取图片数据
if not data:
print("{0} send over...".format(filepath))
break
client_socket.send(data) # 以二进制格式发送图片数据
elif recv_content == 'end':
client_socket.send("end".encode('gbk')) # 发送结束消息
print("结束接收消息~")
break
else:
client_socket.send("你好,我是菜狗!".encode('gbk')) # 发送回复消息
def handler(server_socket):
while True:
client_socket, client_info = server_socket.accept() # 接受客户端连接请求
t1 = Thread(target=recv_data, args=(client_socket, client_info,)) # 创建线程处理接收数据
t1.start() # 启动线程
t1.join() # 等待线程结束
if __name__ == '__main__':
server_socket = socket(AF_INET, SOCK_STREAM) # 创建服务器套接字对象(IPv4和TCP协议)
server_socket.bind(("127.0.0.1", 6551)) # 绑定服务器的IP地址和端口号
server_socket.listen(5) # 开始监听客户端连接请求
print("等待连接!")
handler(server_socket) # 处理客户端连接和数据接收
server_socket.close() # 关闭服务器套接字连接