Socketは、プログラミング言語によるtcp / ipプロトコルのカプセル化です。これを使用して、2つのホスト間でファイルを転送できます。以下は、トピックを直接入力します。次の例は、最も単純なtcp送信コードの例です。サーバーを起動してからクライアントを起動します。 python3socketはバイトタイプのみを送信できることに注意してください。特定の変換については、文字エンコードの章の関連知識を確認してください。
コードを切断する
# - *- coding:utf-8-*-import socket
server = socket.socket()
server.bind(("0.0.0.0",8888))
server.listen(10)while True: #接続されたクライアントのループ監視
conn,addr = server.accept()while True: #各クライアントは接続後も対話を続け、クライアントが切断されると次のクライアントと対話します
try:
rec_data = conn.recv(4096) #4096受信バッファサイズ
iflen(rec_data)==0:breakprint("rec_data:", rec_data.decode(encoding="utf-8"))
conn.send(rec_data.upper())
except ConnectionResetError as e:print("クライアントが接続を閉じました")break
server.close()
クライアントコード
import socket
client = socket.socket()
client.connect(("127.0.0.1",8888))while True:
msg =input()iflen(msg)==0:continue
client.send(msg.encode(encoding="utf-8")) #中国語を送信する場合は、エンコードする必要があり、受信する必要もあります。デコードする必要もあります。英語の直前にbを追加して、タイプを指定します。
client_rec = client.recv(4096)print("client_rec:", client_rec)
client.close()
スティッキーパッケージソリューション:2つのsendステートメントが隣り合っている場合、前の送信の内容と次の送信の内容が混在する状況が発生します。これは、sendがosにデータを送信するだけであり、osがデータを送信する方法を制御できないためです。 、次の方法を使用して、2つのsendステートメント間でメッセージがスタックする問題を解決します
サーバーコード
import socket, os
server = socket.socket()
server.bind(("0.0.0.0",8888))
server.listen(10)while True: #接続されたクライアントのループ監視
conn,addr = server.accept()while True: #クライアントから送信されたgetfilenameを受信し、filenameが存在する場合はファイルを送信し、存在しない場合はファイルを返します。
try:
rec_data = conn.recv(1024) #4096受信バッファサイズ
iflen(rec_data)==0:break
rec_str_list = rec_data.decode(encoding="utf-8").split(" ")
filename = rec_str_list[-1]if os.path.isfile(filename):#ファイルが現在のパスに存在することを判断し、ファイルをクライアントに送信します
file_data =open(filename,encoding="utf-8").read()
conn.send(str(len(file_data)).encode(encoding="utf-8")) #ファイルの長さをクライアントに渡します
print(conn.recv(1024).decode(encoding="utf-8")) #クライアントはファイルの長さを受信して確認メッセージを返し、サーバーは確認メッセージを受信した後にデータの送信を開始します
conn.sendall(file_data.encode(encoding="utf-8"))#すべてのデータをクライアントに送信すると、クライアントはデータが受信されたと判断した後、受信したメッセージを送信します
print(conn.recv(1024).decode(encoding="utf-8")) #クライアントが受信した確認コマンドを受信して、2つの送信が直接接続されてスティッキーパケットが生成されないようにします
else:#ファイル名が存在しない場合は、ファイルが存在しないことを返します
conn.send(b"file is not exit")
except ConnectionResetError as e:print("クライアントが接続を閉じました")break
server.close()
クライアントコード
import socket, os
# get file nameを入力します。ファイルがサーバーのホームディレクトリに存在する場合、ファイルが返され、クライアントはファイルの内容を受信して印刷します。
client = socket.socket()
client.connect(("127.0.0.1",8888))while True:
msg =input()iflen(msg)==0:continue
client.send(msg.encode(encoding="utf-8")) #中国語を送信する場合は、エンコードする必要があり、受信する必要もあります。デコードする必要もあります。英語の直前にbを追加して、タイプを指定します。
client_rec = client.recv(1024).decode(encoding="utf-8")print("client_rec", client_rec)if client_rec =="file is not exit": #ファイルが存在しない場合、ユーザーはファイルが存在しないと印刷し、ユーザーは入力を続けます
print(client_rec)continue
client.send(client_rec.encode(encoding="utf-8"))#ファイルが存在する場合は、ファイルサイズを送り返します
rec_len =int(client_rec)print("rec_len", rec_len)
file_len =0
new_file =open("new_file","a",encoding="utf-8")while file_len < rec_len:#受信したファイルのサイズがサーバーから送信したサイズと同じになるまで、ループでファイルの受信を開始します,受信したデータを新しいファイルに書き込みます
rec_data_tmp = client.recv(1024)
file_len +=len(rec_data_tmp)print("receive date len", file_len)
new_file.write(rec_data_tmp.decode(encoding="utf-8"))
client.send("receive all".encode(encoding="utf-8"))
client.close()
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts