以下是您提供的Python代码的每一行的解释:
import socket
import os
import sys
import struct
- 导入所需的模块:socket用于网络通信,os用于文件操作,sys用于系统相关操作,struct用于处理二进制数据。
def socket_service_image():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind(('127.0.0.1', 6666))
s.bind(('192.168.8.63', 6666))
s.listen(10)
except socket.error as msg:
print(msg)
sys.exit(1)
print("Wait for Connection................")
while True:
sock, addr = s.accept() # addr是一个元组(ip,port)
deal_image(sock, addr)
- 定义一个名为
socket_service_image
的函数,用于启动服务,监听客户端连接。 - 创建一个TCP socket对象,并设置地址重用选项。
- 绑定IP地址和端口号(这里使用IP地址为’192.168.8.63’,端口号为6666)。
- 开始监听并接受最多10个连接请求。
- 进入无限循环,等待客户端连接。
- 一旦有连接请求被接受,将连接对象和客户端地址传递给
deal_image
函数进行处理。
def deal_image(sock, addr):
print("Accept connection from {0}".format(addr)) # 查看发送端的IP和端口
while True:
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('./',
'new_' + fn) # 在服务端新建图片名(可以不用新建的,)
recvd_size = 0
fp = open(new_filename, 'wb')
while not recvd_size == filesize:
if filesize - recvd_size > 1024:
data = sock.recv(1024)
recvd_size += len(data)
else:
data = sock.recv(1024)
recvd_size = fileinfo_size
fp.write(data) # 写入图片数据
sock.close()
break
- 定义一个名为
deal_image
的函数,用于处理接收到的图片数据。 - 打印连接的发送方的IP地址和端口号。
- 进入无限循环,持续接收图片数据。
- 计算接收文件名和文件大小的数据的大小。
- 接收文件名和文件大小的数据,并解包为文件名和文件大小。
- 对文件名进行解码和处理。
- 根据处理后的文件名在服务端创建一个新的文件。
- 进入接收数据的循环,直到接收到的数据大小等于文件大小。
- 如果剩余文件大小大于1024字节,则接收1024字节的数据,同时更新已接收数据的大小。
- 如果剩余文件大小不超过1024字节,则接收剩余的数据,并将已接收数据的大小更新为文件名和文件大小数据的大小。
- 将接收的数据写入文件。
- 关闭socket连接。
- 结束循环并退出函数。
if __name__ == '__main__':
socket_service_image()
服务端:
import socket import os import sys import struct def sock_client_image(): while True: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # s.connect(('服务器的ip',6666))# 服务器和客户端在不同的系统或不同的主机下时使用的ip 和端口,首先要查看服务器所在的系统网卡的ip s.connect(('192.168.8.63', 6666)) # 服务器和客户端都在一个系统下时使用的ip和端口 except socket.error as msg: print(msg) print(sys.exit(1)) filepath = input('input the file: ') fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size) # 将xxx.jpg以128sq的格式打包 s.send(fhead) fp = open(filepath, 'rb') while True: data = fp.read(1024) # 读入图片数据 if not data: print('{0} send over....'.format(filepath)) break s.send(data) # 以二进制格式发送图片数据 s.close() # break # 循环发送 if __name__ == '__main__': sock_client_image()
import socket
: 导入socket库,用于创建网络连接。import os
: 导入os库,用于操作文件路径。import sys
: 导入sys库,用于与Python解释器进行交互。import struct
: 导入struct库,用于处理二进制数据。def sock_client_image():
: 定义一个名为sock_client_image的函数。while True:
: 进入无限循环,保持程序运行。s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
: 创建一个TCP socket对象。s.connect(('192.168.8.63', 6666))
: 连接服务器的IP地址和端口号,与服务器建立连接。filepath = input('input the file: ')
: 从用户输入获取文件路径。fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),os.stat(filepath).st_size)
: 使用struct.pack将文件名和文件大小打包为二进制数据。s.send(fhead)
: 将打包的文件头信息发送到服务器。fp = open(filepath, 'rb')
: 以二进制只读模式打开文件。while True:
: 进入循环,读取文件数据并发送给服务器。data = fp.read(1024)
: 从文件中读取1024字节的数据。s.send(data)
: 将读取的数据发送到服务器。s.close()
: 关闭socket连接。if __name__ == '__main__':
: 程序入口,如果该脚本直接执行而不是被导入,则执行下面的代码。sock_client_image()
: 调用sock_client_image函数。