pythonネットワーク(二、転送ファイル)
7587 ワード
初志
まず、私がこの文章を書いた初心を話します.多くの場合、vmware workstation仮想マシンと私の物理マシンの間で情報を伝える必要があります.Uディスクをキャリアとして逆さまにするのは面倒です.しかし、一般的にはすべてのシステムにpythonをインストールします(もちろんCで実現するのはもっと安全ですが、.exeとELFの2つのファイルが必要です).そこで、私は自分でpythonスクリプトを作って、このような「仮想マシンと物理マシン」と「仮想マシンの間」のファイル転送を便利にしたいと思っています.
初めての試み
サーバさーば:ファイルの受信ふぁいるのじゅしん
クライアント:ファイルの転送
pythonスクリプトに濃縮
上記のコードは、簡潔化のためにクライアントとサーバコードを分離します.しかし、配置を容易にするために、以下にファイルを作成します.
file_transer.py
もう少し改善する時間がある
1. フォルダの再帰転送は現在サポートされていません
2. 現在はマルチスレッド転送ではなく、速度はまだ速くありません(ただし、シングルマシンでの転送の影響は大きくありません)
3. 現在は現在のフォルダでの転送のみがサポートされていますので、パスの指定を許可したほうがいいです.
まず、私がこの文章を書いた初心を話します.多くの場合、vmware workstation仮想マシンと私の物理マシンの間で情報を伝える必要があります.Uディスクをキャリアとして逆さまにするのは面倒です.しかし、一般的にはすべてのシステムにpythonをインストールします(もちろんCで実現するのはもっと安全ですが、.exeとELFの2つのファイルが必要です).そこで、私は自分でpythonスクリプトを作って、このような「仮想マシンと物理マシン」と「仮想マシンの間」のファイル転送を便利にしたいと思っています.
初めての試み
サーバさーば:ファイルの受信ふぁいるのじゅしん
# -*- coding: cp936 -*-
from socket import *
import struct
import os
ratio_base=0.00
def print_ratio(ratio, delta=1.00):
global ratio_base
if ratio > ratio_base + delta:
ratio_base = ratio_base + delta
print " %4.2f"%ratio,
print "%"
else:
pass
if __name__ == "__main__":
ADDR = ('127.0.0.1',8000)
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')
recvSock = socket(AF_INET,SOCK_STREAM)
recvSock.bind(ADDR)
recvSock.listen(5)
conn,addr = recvSock.accept()
fhead = conn.recv(FILEINFO_SIZE)
filename,temp1,filesize,temp2=struct.unpack('128s32sI8s',fhead)
filename = filename.strip('\00') #???
if os.path.isfile(filename):
filename = raw_input(" , [default: new_%s] "%filename)
if filename.strip() == "":
filename = 'new_'+filename.strip('\00')
else:
filename = filename.strip('\00')
fp = open(filename,'wb')
restsize = filesize
while True:
if restsize > BUFSIZE:
filedata = conn.recv(BUFSIZE)
else:
filedata = conn.recv(restsize)
if not filedata:
break
fp.write(filedata)
restsize = restsize-len(filedata)
ratio = ( float(filesize) - float(restsize) ) / float(filesize) * 100
print_ratio(ratio)
if restsize == 0:
break
fp.close()
conn.close()
recvSock.close()
print "received all"
クライアント:ファイルの転送
# -*- coding: cp936 -*-
from socket import *
import os
import struct
if __name__ == "__main__":
ADDR = ('127.0.0.1',8000)
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')
filename = raw_input("file to be sent under this dir: ") #' .rmvb'
fhead=struct.pack('128s11I',filename,0,0,0,0,0,0,0,0,os.stat(filename).st_size,0,0)
sendSock = socket(AF_INET,SOCK_STREAM)
sendSock.connect(ADDR)
sendSock.send(fhead)
fp = open(filename,'rb')
while True:
filedata = fp.read(BUFSIZE)
if not filedata:
break
sendSock.send(filedata)
fp.close()
sendSock.close()
print "sent all"
pythonスクリプトに濃縮
上記のコードは、簡潔化のためにクライアントとサーバコードを分離します.しかし、配置を容易にするために、以下にファイルを作成します.
file_transer.py
# -*- coding: cp936 -*-
from socket import *
import struct
import os
ratio_base=0.00
def print_ratio(ratio, delta=1.00):
global ratio_base
if ratio > ratio_base + delta:
ratio_base = ratio_base + delta
print " %4.2f"%ratio,
print "%"
else:
pass
def client_sender():
print "current directory : ", os.getcwd()
#print os.listdir(os.getcwd())
server_ip = raw_input("receiver's ip : ")
server_port = raw_input("receiver's port : ")
ADDR = (server_ip, int(server_port) )
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')
while True:
try:
filename = raw_input("file to be sent under this dir: ") #' .rmvb'
fhead=struct.pack('128s11I',filename,0,0,0,0,0,0,0,0,os.stat(filename).st_size,0,0)
sendSock = socket(AF_INET,SOCK_STREAM)
sendSock.connect(ADDR)
sendSock.send(fhead)
fp = open(filename,'rb')
while True:
filedata = fp.read(BUFSIZE)
if not filedata:
break
sendSock.send(filedata)
fp.close()
print "sent"
except:
print "sent error"
sendSock.close()
def server_receiver():
print "my ip : (ipconfig / ifconfig)"
server_port = raw_input("my port : ")
print "waiting for file ..."
ADDR = ("", int(server_port)) #note: DO NOT USE "127.0.0.1"
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')
recvSock = socket(AF_INET,SOCK_STREAM)
recvSock.bind(ADDR)
recvSock.listen(5)
while True:
try:
conn,addr = recvSock.accept()
fhead = conn.recv(FILEINFO_SIZE)
filename,temp1,filesize,temp2=struct.unpack('128s32sI8s',fhead)
filename = filename.strip('\00') #???
if os.path.isfile(filename):
filename = raw_input(" , [default: new_%s] "%filename)
if filename.strip() == "":
filename = 'new_'+filename.strip('\00')
else:
filename = filename.strip('\00')
fp = open(filename,'wb')
restsize = filesize
while True:
if restsize > BUFSIZE:
filedata = conn.recv(BUFSIZE)
else:
filedata = conn.recv(restsize)
if not filedata:
break
fp.write(filedata)
restsize = restsize-len(filedata)
ratio = ( float(filesize) - float(restsize) ) / float(filesize) * 100
print_ratio(ratio)
if restsize == 0:
break
fp.close()
conn.close()
print filename, " received"
except:
print "receive error"
recvSock.close()
if __name__ == "__main__":
choice = raw_input("send or receive [s/r] : ")
if choice == "s":
client_sender()
print
elif choice == "r":
server_receiver()
print
else:
print "oops..."
もう少し改善する時間がある
1. フォルダの再帰転送は現在サポートされていません
2. 現在はマルチスレッド転送ではなく、速度はまだ速くありません(ただし、シングルマシンでの転送の影響は大きくありません)
3. 現在は現在のフォルダでの転送のみがサポートされていますので、パスの指定を許可したほうがいいです.