使用Python套接字编程将图像文件从服务器传输到客户端
我正在做一个项目,使用我的安卓手机拍照,然后把这些照片存储在SD卡的文件夹里。我正在写一个Python脚本,想定期把这些文件夹从SD卡移动到我电脑上的一个特定文件夹里。我的手机和电脑是通过手机热点连接的。
我写了一个套接字程序,电脑作为客户端,手机作为服务器。但是我遇到了一些问题。虽然我没能成功移动文件夹,但我尝试从文件夹中移动图片,结果遇到了以下问题:
- 图片被复制成了一个未知的文件格式。
- 我无法在服务器端循环处理,以移动文件夹中所有的图片。
- 在客户端,我无法把图片存储到我想要的位置。我试图在发送图片之前,从服务器发送文件夹名称和文件名称,但客户端没有接受我发送的文件名称,而是去寻找一个同名的文件夹。
- 我在发送给客户端的名称大小上也遇到了问题,我该如何根据从服务器发送的名称随机调整客户端的名称大小。
我需要有人帮我解决这个问题。
这是客户端的代码
import socket,os
import time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("192.168.43.1", 5005))
size = 1024
while True:
fln = client_socket.recv(size) # folder name
fn = client_socket.recv(size) # file name
fname = "E:\\Transfered\\"+fln+"\\"+fn
fp = open(fname,'w')
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#data = 'viewnior '+fname
#os.system(data)
这是服务器端的代码
import os
import sys,time
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5005))
server_socket.listen(5)
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
sb = '/mnt/sdcard/sb'
while True:
files = os.listdir(sb)
pages = 0;
while (files):
print '\nMaybe, pending work'
for au in files:
if (au.find('d')>-1): # searching for folder with a d
os.chdir(sb+'/'+au)
imgFiles = os.listdir(sb+'/'+au)
images = [img for img in imgFiles if img.endswith('.jpg')]
print '\n%s user done' %au
client_socket.send(au)
pages = 0;
#copies all .img files in the folder from server to client
for imgs in images:
print imgs
client_socket.send(imgs)
file_name = open(imgs,'r')
while True:
strng = file_name.readline(1024)
if not strng:
break
client_socket.send(strng)
file_name.close()
print "Data sent successfully"
os.remove(sb+'/'+au+'/'+imgs)
pages = pages + 1
time.sleep(1)
os.chdir(sb)
os.rmdir(au)
else:
time.sleep(2)
exit()
2 个回答
-1
我已经修改了代码,解决了很多问题,现在我想解决的唯一问题就是图像传输。我在客户端打开了一个 .jpg 文件,并把数据写入了这个文件。但是最终的文件大小比原来的小了1KB。我想如果能解决这个问题,我的工作就完成了。有没有人能帮我一下?
这是代码
服务器:
import os
import sys,time
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5005))
server_socket.listen(5)
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
sb = '/mnt/sdcard/sb'
while True:
files = os.listdir(sb)
pages = 0;
while (files):
print '\nMaybe, pending work'
for au in files:
if (au.find('d')>-1):
os.chdir(sb+'/'+au)
imgFiles = os.listdir(sb+'/'+au)
images = [img for img in imgFiles if img.endswith('.jpg')]
print '\n%s user done' %au
client_socket.send(au)
#copies all .img files in the folder from server to client
for imgs in images:
client_socket.send(imgs)
file_name = open(imgs,'rb')
while True:
strng = file_name.readline()
if not strng:
break
client_socket.send(strng)
file_name.close()
os.remove(sb+'/'+au+'/'+imgs)
print "Data sent successfully"
time.sleep(1)
os.chdir(sb)
os.rmdir(au)
else:
time.sleep(2)
exit()
客户端:
import socket,os
import time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("192.168.43.1", 5005))
dst="E:\\Kiosk\\"
while True:
#folder name
fln = client_socket.recv(4)
os.chdir(dst);
dst = "E:\\Kiosk\\"+fln+"\\"
if not os.path.exists(dst): os.makedirs(dst)
fname = client_socket.recv(4)
os.chdir(dst)
fname = fname+'.jpg'
fp = open(fname,'wb')
# image
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#time.sleep(10)
#data = 'viewnior '+fname
#os.system(data)
1
这个问题似乎是因为在服务器端对一个二进制文件使用了 readline()
函数:
file_name = open(imgs,'rb')
while True:
strng = file_name.readline()
readline()
是用来从文件中读取数据,直到遇到下一个 '\n'
字符为止。如果在二进制文件上使用这个函数,可能会读取到非常大的数据块!(甚至可能一直读取到文件末尾)。在这种情况下,使用 socket.send()
发送数据可能无法发送完整的数据,因此需要检查返回值(即实际发送的字节数)。解决这个问题的方法有:
- 使用
socket.sendall()
来发送数据,这样可以确保发送整个数据块。
或者,另外一种方法(可以同时使用这两种方法):
- 使用
file_name.read(1024)
- 这样可以限制每次读取的数据量。