一、保证要传输文件的两个电脑在同一个局域网下(即同一个wifi下)。
二、有两部分程序,分为sender和reciever两部分,sender放在要发送的电脑上,reciever放在要接受文件的电脑上。该程序可以实现某个文件内文件数量变化时,将新增的文件实时传输过去。
1、sender部分:
# coding = utf-8
import socket # socket库的用法,详细参考浏览器收藏夹
import os
import sys
import struct # 该库将用户定义的数据类型和文件io关联起来,用二进制模式来写这些数据
import time
def sock_client(file,final):
try:
# socket.SOCK_STREAM 表示指定使用面向连接的TCP协议,socket.AF_INET表示指定使用IPv4协议
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 需要连接的电脑的IP地址和端口,该函数是发送文件,需要输入接收方电脑的ipv4地址,端口可以找一个空闲的,一般大于5000是空闲的
s.connect(('192.168.1.180', 45795))
except socket.error as msg:
print(msg)
print(sys.exit(1)) # sys.exit(1)是当程序异常结束时,返回1。程序正常结束时,返回0.
while True:
# 传输一张EL图片用时12ms
origin=os.listdir(file) # 遍历文件夹,返回文件和文件夹名字
set1=set(origin) # 创建一个无序的元素集
set2=set(final)
filepath_diff=set1^set2 # 找取两个元素集不一样的元素
start=time.time() # 返回当前时刻
# 定义文件信息,128s表示文件名为128bytes长,l表示一个int或log文件类型
# struct.pack是对图片字节大小进行一个包装,然后发送(这一步并不是发送图片),,把数据封装成字符串(实际上是类似于c结构体的字节流)
# struct.pack()、struct.unpack()和struct.calcsize()具体用法找度娘
for filepath in filepath_diff:
final.append(filepath)
filepath=f'{file}{filepath}' # 拼接路径
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.1.180', 6666))
fhead = struct.pack(b'128sqs', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size,bytes('a', encoding='utf-8'))
s.send(fhead)
# print('client filepath: {0}'.format(filepath))
fp = open(filepath, 'rb')
while 1:
data = fp.read(1024)
if not data:
print('{0} file send over...'.format(filepath))
break
s.send(data)
end=time.time()
print(end-start)
s.close()
# break
if __name__ == '__main__':
file='图片\\'
sock_client(file,[])
其中struct.pack()、struct.unpack()的参数问题如下:
2、reciever部分:
# coding = utf-8
'''
接收端(服务端,用来接受客户端发来的图片)
'''
import socket
import os
import sys
import struct
def socket_service_image():
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('192.168.1.180',6666)) #IP地址和端口号需要根据自己的来设置
s.listen(10) #开始监听端口,最多能监听10个
except socket.error as msg:
print(msg)
sys.exit(1)
print("Wait for Connection.....................")
while True:
sock,addr=s.accept() #等待与客户端的连接,addr是连接地址,
deal_image(sock,addr)
def deal_image(sock,addr):
while True:
fileinfo_size=struct.calcsize('128sqs')
buf=sock.recv(fileinfo_size) #接收图片名和图片的字节大小
if buf:
filename,filesize,computername=struct.unpack('128sqs',buf) # 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
fn=filename.decode().strip('\x00')
computername = computername.decode().strip('\x00')
new_filename=os.path.join(computername,'new_'+fn)
recv_size=0 #用来记录传输的字节数
if not os.path.isdir(computername): # 若不存在该文件夹,则创建一个
os.makedirs(computername)
fp=open(new_filename,'wb')
while recv_size!=filesize:
if filesize-recv_size>1024:
data=sock.recv(1024)
recv_size+=1024
else:
data=sock.recv(1024)
recv_size=filesize
fp.write(data) #写入图片数据
fp.close()
sock.close()
break
if __name__ == '__main__':
socket_service_image()