Pythonはftpファイル転送機能を実装しています

この記事の例では、参照用にftpファイル転送を実現するためのpythonの特定のコードを共有しています。具体的な内容は次のとおりです。

主な手順は、次の手順に分けることができます。

  1. ファイル名を読み取る
  2. ファイルが存在するかどうかを確認します
  3. ファイルを開く
  4. ファイルサイズを検出する
  5. ファイルサイズとmd5値をクライアントに送信します
  6. クライアントの確認を待つ
  7. 読み取り中にデータの送信を開始する

サーバー側のコード:

import socket,os,time
import hashlib
 
server =socket.socket()
server.bind(('0.0.0.0',6666))
server.listen()print("待つ....")while True:
 conn,addr = server.accept()print("new conn:",conn)while True:
 data = conn.recv(1024)if not data:print("client is disconnection")break
 cmd,filename = data.decode().split() #指示とファイル名を記録する
 print(filename)
 # ファイルが現在のディレクトリに存在するかどうかを確認します。ファイルはディレクトリではなくファイルである必要があります
 if os.path.isfile(filename):
 f =open(filename,'rb')
 # m = hashlib.md5() #md5を作成します
 file_size = os.stat(filename).st_size #stat()ファイルのサイズを返すことができます
 conn.send((str(file_size)).encode()) #送信ファイルサイズ
 conn.recv(1024) #返品情報を待っています
 for line in f:
 # m.updata(line) 
 conn.send(line)
 # print("file md5",m.hexdigest()) #md5値を出力
 f.close()

クライアントコード:

# Author: zjt
import socket
 
client = socket.socket()
 
client.connect(("0.0.0.0",6666))while True:
 cmd =input("   :").strip()iflen(cmd)==0:continueif cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)print("server response: ",server_response)
 client.send(b"ready to recv file")
 
 # ファイルの受信を開始します
 file_total_size =int(server_response.decode())
 received_size =0 #受信したファイルのサイズを記録します
 filename = cmd.split()[1]
 # 2つのディレクトリは一貫しているため、受信したファイル名を元のファイルと同じにすることはできません。
 f =open(filename+".new","wb")while received_size < file_total_size:
 data = client.recv(1024)
 received_size +=len(data)
 f.write(data)print("total:",file_total_size," present: ",received_size)else:print("file has received done!")
 f.close()
 
client.close()

80Mファイル転送テストを使用します。効果は次のとおりです。

プログラムのアップグレード:

以前のコードでは検証用のmd5が追加されていませんでしたが、コードがアップグレードされました

サーバー側のコード:

import socket,os,time
import hashlib
 
server =socket.socket()
server.bind(('0.0.0.0',8888))
server.listen()print("待つ....")while True:
 conn,addr = server.accept()print("new conn:",conn)while True:
 data = conn.recv(1024)if not data:print("client is disconnection")break
 cmd,filename = data.decode().split() #指示とファイル名を記録する
 print(filename)
 # ファイルが現在のディレクトリに存在するかどうかを確認します。ファイルはディレクトリではなくファイルである必要があります
 if os.path.isfile(filename):
 f =open(filename,'rb')
 m = hashlib.md5() #md5を作成します
 file_size = os.stat(filename).st_size #stat()ファイルのサイズを返すことができます
 conn.send((str(file_size)).encode()) #送信ファイルサイズ
 conn.recv(1024) #返品情報を待っています
 for line in f:
 m.update(line)
 conn.send(line)print("file md5",m.hexdigest()) #md5値を出力
 
 f.close()
 conn.send(m.hexdigest().encode()) #md5を送信します
 
 print("本当に送った",m.hexdigest().encode())print("send done")
 
server.close()

クライアントコード:

import socket
import hashlib
client = socket.socket()
client.connect(("0.0.0.0",8888))while True:
 cmd =input("   :").strip()iflen(cmd)==0:continueif cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)print("server response: ",server_response)
 client.send(b"ready to recv file")
 # ファイルの受信を開始します
 file_total_size =int(server_response.decode())
 received_size =0 #受信したファイルのサイズを記録します
 filename = cmd.split()[1]
 # 2つのディレクトリは一貫しているため、受信したファイル名を元のファイルと同じにすることはできません。
 f =open(filename+".new","wb")
 m = hashlib.md5()while received_size < file_total_size:
 data = client.recv(1024)
 received_size +=len(data)
 m.update(data)
 f.write(data)
 # print("total:",file_total_size," present: ",received_size)else:
 new_file_md5 = m.hexdigest()print("client file md5:",new_file_md5)print("file has received done!")print("total:",file_total_size," present: ",received_size)
 f.close()
 sever_file_md5 = client.recv(1024)print("client file md5:",new_file_md5)print("server file md5:",sever_file_md5)
client.close()

2つのプログラムはLinux環境で実行され、結果は次のようになります。

転送後にファイルサイズが少し大きくなり、md5の前後の値も異なり、ファイル転送が変更されたことを示していることがわかります。

次に、Windows環境で実行されているプログラムについて説明します。結果は次のとおりです。

この時点で、Windowsで問題がなく、ファイルサイズが同じであり、md5値も同じであることがわかります。

原因分析:

これは、Linuxで実行しているときに、最後のファイル転送中にスティッカブルパケットが発生し、md5値が送信されたため、ファイルが最後に受信され、md5データが一緒に送信されたために発生します。また、クライアントは受信した情報の一部として扱われ、すべて受信されます。したがって、クライアントはサーバーからmd5値を受け取りません。少し余分なのは、md5値のサイズです。

解決:

ファイルを受信するときは、現在受信できるファイルの数を確認します。1024より大きい場合は、1024サイズのファイルを受信します。それ以外の場合は、残りのすべてのファイルのみを受信して、最後に冗長データを受信しないようにします。

クライアントコードを変更するだけで、変更されたコードは次のとおりです。

import socket
import hashlib
client = socket.socket()
client.connect(("0.0.0.0",8888))while True:
 cmd =input("   :").strip()iflen(cmd)==0:continueif cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)print("server response: ",server_response)
 client.send(b"ready to recv file")
 # ファイルの受信を開始します
 file_total_size =int(server_response.decode())
 received_size =0 #受信したファイルのサイズを記録します
 filename = cmd.split()[1]
 f =open(filename+".new","wb")
 m = hashlib.md5()while received_size < file_total_size:
 # 前回の残り分をできるだけ多く受け取り、くっつかないように判断してください。
 if file_total_size - received_size   1024:
 size =1024else: #前回、残り金額
 size = file_total_size - received_size
 data = client.recv(size)
 received_size +=len(data)
 m.update(data)
 f.write(data)else:
 new_file_md5 = m.hexdigest()print("client file md5:",new_file_md5)print("file has received done!")print("total:",file_total_size," present: ",received_size)print("次の文はファイルを閉じます")
 f.close()print("md5の受信を開始します") 
 sever_file_md5 = client.recv(1024)print("client file md5:",new_file_md5)print("server file md5:",sever_file_md5)
client.close()

以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。

Recommended Posts

Pythonはftpファイル転送機能を実装しています
PythonはTCPファイル転送を実装します
PythonがFTP機能を実装する方法
Pythonトルネードアップロードファイル機能
Pythonは画像スティッチング機能を実装しています
Pythonがメール機能を実装する方法
PythonはAIフェイスチェンジ機能を実装しています
Pythonがタイマー機能を実装する方法
Pythonファイル操作
python_ファイル処理
Python enumerate()関数
Python関数バッファー
Pythonはスーパーマリオを実装しています
Pythonはtic-tac-toeゲームを実装しています
Pythonカスタム関数の基本
Pythonの結合関数
Python組み込み関数-compile()
Pythonはマンマシンゴバンを実装します
Python関数の基礎学習
Pythonデータ分析-関数の適用
Pythonは画像スティッチングを実装しています
Python3組み込み関数table.md
Pythonはスキャンツールを実装しています
Pythonプリントプリントタイマー機能
Pythonはしきい値回帰を実装します
Pythonは地雷除去ゲームを実装しています
PythonはFTPを実装して、ファイルをループでアップロードします
Pythonは電子辞書を実装しています
Pythonは推測ゲームを実装しています
Pythonは関数メソッドを定義します
Pythonは単純なタンクバトルを実装します
Pythonはudpチャットウィンドウを実装します
Pythonはオンライン翻訳機能を実現します
Pythonは推測ゲームを実装しています
Pythonは駐車場管理システムを実現
Pythonはデジタル爆弾ゲームを実装しています
Pythonnumpyはローリングケースを実装します
OpenCVPythonはパズルゲームを実装しています
Pythonは単純なtic-tac-toeゲームを実装しています
Pythonはパスワード強度検証を実装します
Pythonは車の管理システムを実装しています
Pythonはコードブロックフォールディングを実装します
Pythonはパノラマ画像スティッチングを実装しています
Pythonマジック関数eval()学習
PythonはSMTPメール送信を実装します
Pythonは多次元配列ソートを実装しています
Pythonは平均シフトクラスタリングアルゴリズムを実装しています
Pythonは検証コード認識を実装します
Pythonは勾配降下法を実装しています
Pythonはテキストバージョンのminesweeperを実装しています
クイックスタートPythonファイル操作
Pythonの上位関数の使用法の概要!
Pythonは実店舗のゲームを実装しています