服务端
-
import socket
: 导入Python内置的socket库,用于实现基于Socket的网络通信。 -
import sys
: 导入sys模块,该模块提供了与Python解释器和其环境有关的变量和函数。 -
import os
: 导入os模块,该模块提供了与操作系统交互的功能。 -
import struct
: 导入struct模块,该模块用于处理二进制数据的打包和解包。 -
def socket_server_image():
: 定义一个名为socket_server_image()
的函数,用于启动图片服务器。 -
try:
: 引入异常处理逻辑。 -
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
: 创建一个TCP/IP类型的socket对象。 -
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
: 设置socket选项以允许地址重用。 -
s.bind(('127.0.0.1', 8887))
: 将服务器绑定到指定的IP地址(127.0.0.1)和端口号(8887)。 -
s.listen(10)
: 开始监听连接请求,最多允许10个连接同时排队等待。 -
except socket.error as msg:
: 如果发生socket错误,则捕获异常。 -
print(msg)
: 打印错误消息。 -
sys.exit(1)
: 退出程序。 -
print('Wait for Connection.................')
: 打印等待连接的消息。 -
while True:
: 无限循环,等待客户端连接。 -
sock, addr = s.accept()
: 接受客户端的连接请求,并返回一个新的socket对象和客户端的地址。 -
a = sock.recv(1024)
: 从客户端接收数据,每次最多接收1024字节。 -
b = a.decode('gbk')
: 将接收到的字节数据解码为字符串,使用’gbk’编码格式。 -
print(f'客户端说:{b}')
: 打印客户端发送的消息。 -
deal_image(sock, addr)
: 调用deal_image()
函数处理接收到的图片数据。 -
def deal_image(sock, addr):
: 定义一个名为deal_image()
的函数,用于处理图片数据。 -
print('Accept connection from {0}'.format(addr))
: 打印客户端的地址信息。 -
while True:
: 无限循环,接收多个图片文件。 -
filepath = input('input the file:')
: 获取用户输入的文件路径。 -
fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)
: 根据文件名和文件大小创建一个固定长度的数据包。 -
sock.send(fhead)
: 发送数据包给客户端。 -
fp = open(filepath, 'rb')
: 打开指定文件,以二进制读取模式。 -
while True:
: 无限循环,不断读取文件内容并发送。 -
data = fp.read(1024)
: 从文件中读取最多1024字节的数据。 -
if not data:
: 如果读取到文件末尾。 -
print('{0} send over...'.format(filepath))
: 打印文件传输完成的消息。 -
break
: 跳出当前循环。 -
sock.send(data)
: 发送读取到的数据给客户端。 -
sock.close()
: 关闭socket连接。 -
if __name__ == '__main__':
: 如果当前脚本作为主程序运行: -
socket_server_image()
: 调用socket_server_image()
函数启动图片服务器。
客户端
-
import socket
: 导入Python内置的socket库,用于实现基于Socket的网络通信。 -
import sys
: 导入sys模块,该模块提供了与Python解释器和其环境有关的变量和函数。 -
import os
: 导入os模块,该模块提供了与操作系统交互的功能。 -
import struct
: 导入struct模块,该模块用于处理二进制数据的打包和解包。 -
def sock_client_image():
: 定义一个名为sock_client_image()
的函数,用于连接到图片服务器并接收图片。 -
while True:
: 无限循环,保持与服务器的连接。 -
try:
: 引入异常处理逻辑。 -
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
: 创建一个TCP/IP类型的socket对象。 -
s.connect(('127.0.0.1', 8887))
: 尝试连接到指定的IP地址(127.0.0.1)和端口号(8887)的服务器。 -
except socket.error as msg:
: 如果发生socket错误,则捕获异常。 -
print(msg)
: 打印错误消息。 -
print(sys.exit(1))
: 退出程序。 -
msg = input('>')
: 获取用户输入的消息。 -
s.send(msg.encode('gbk'))
: 将用户输入的消息编码为字节流并发送给服务器。 -
filepath_size = struct.calcsize('128sq')
: 计算固定大小的数据包的长度。 -
buf = s.recv(filepath_size)
: 接收指定长度的数据包。 -
if buf:
: 如果接收到了数据。 -
filename, filesize = struct.unpack('128sq', buf)
: 解包接收到的数据包,得到文件名和文件大小。 -
fn = filename.decode().strip('\x00')
: 将文件名字节流解码为字符串,并去除末尾的空字符。 -
new_filename = os.path.join('./', 'new_' + fn)
: 构建新的文件名,添加前缀’new_'。 -
recvd_size = 0
: 初始化已接收的文件大小为0。 -
fp = open(new_filename, 'wb')
: 打开一个新的文件以二进制写入模式。 -
while not recvd_size == filesize:
: 当未接收到的文件大小等于文件总大小时进行循环。 -
if filesize - recvd_size > 1024:
: 如果剩余大小大于1024字节。 -
data = s.recv(1024)
: 接收最多1024字节的数据。 -
recvd_size += len(data)
: 更新已接收的文件大小。 -
else:
: 如果剩余大小小于等于1024字节。 -
data = s.recv(1024)
: 接收剩余的数据。 -
recvd_size = filesize
: 更新已接收的文件大小为文件总大小。 -
fp.write(data)
: 将接收到的数据写入文件。 -
fp.close()
: 关闭文件。 -
if __name__ == '__main__':
: 如果当前脚本作为主程序运行: -
sock_client_image()
: 调用sock_client_image()
函数连接到服务器并接收图片