+スティックパッケージを解決するためにファイルを転送するTCP

#スティック包装を解い
**のみTCPパケットが粘着性の現象があり、UDPは**パッケージスティックはありません

** **スティックパッケージには、基本的に私は充電にどのくらい知っていない理由である
、それは粘着性のパッケージで、その結果、受信側が必要と一度受けすぎて、次回1.tcp
、メッセージのカーネルモードメモリの内容は、数の少ないに送られた2.tcpをクライアントは一度だけ受けたので、そこNigon TCPアルゴリズム、少ないし、複数のコンテンツパッケージ、オペレーティングシステム、およびの合成は、受信した全体的に、送り出さ

TCP:エンドとB-エンド通信接続、送信側、B側が受け取ることができ
UDP:のsendtoの一端を、Bはのrecvfromの終わり対応している必要があり、Bは、実際に受信終了することができます
髪場合> UDPを一度受け、すべての失われた部分を受け取っていません

**ソリューション
まず髪のボリュームデータ、第二の再送データ
選択nバイトの前に2、データの残りの長さを含みます

**ジェイソン溶液ヘッダは、後続の処理の容易にするために、付加情報ファイルにアクセスするのdictする
サーバ
`Pythonの
インポートソケット
インポートサブプロセス
インポート構造体
インポートJSONを

サーバ= socket.socket()
server.bind(( '127.0.0.1'、8081))
server.listen(5)

真の中:
コネティカット、ADDR = server.accept()
印刷(「接続に成功」)
しばらく真:
試してみる:
CMD = conn.recv(1024)
印刷(「受信成功」)
のTCPクライアントがヌル送信、サーバーにつながりますラム生きる(つまり、ヘッダ、アドレスとポート情報が付属しているので、UDP、この問題を持っていない)
(CMD)== 0 lenの場合:BREAKの
CMD = cmd.decode(「UTF-8」)
新しいプロセスを開くために#使用サブプロセスを、かもしれませんコマンドを受信し、この文字列を実行するためにシェルを呼び出し
OBJ = subprocess.Popen(CMD、シェル= Trueの場合、STDOUT = subprocess.PIPE、標準エラー出力= subprocess.PIPE)
シェルの標準化と標準化された報告書虚偽の情報のサブプロセス出力受ける#res
= RESをobj.stdout.read()+ obj.stderr.read()
長、辞書作成、モジュールによって返された情報を提供するために必要な他の情報
D = { 'FILE_SIZE':LEN (RES)、 '情報を見ます'。 「XXXXXXX」}
辞書シリアライゼーション
json_d = json.dumps(D)
#1の最初のプロンプトのクライアントを作る、ヘッダ送信する辞書の長さ
(#構造体モジュール、int型の長さは、バイナリ文字列に変換し、唯一の4バイト)
= struct.packヘッダ( 'I'は、LEN(json_d))
ヘッダ2 struct.pack =( 'I'は、(json_d.encode( 'UTF8')LEN))文に同じ効果で、バイトの長さをカウントします

#2送信辞書ヘッダ
conn.send(ヘッダ)
#3送信辞書
conn.send(json_d.encode( 'UTF-8'))
#4再発実データ
conn.send(RES)
#1 conn.send( obj.stdout.read())
のconn.send(obj.stderr.read())
を除くConnectionResetError:
BREAK
はconn.close()
`` `

クライアント
`` `Pythonの
インポートソケット
のインポート構造体
のインポートJSON

= socket.socketクライアント()
client.connect(( '127.0.0.1'、8081))
を印刷( '接続に成功')
真中:
MSG = INPUT。( '>>>:')(エンコード'UTF-8' )
#のTCPクライアントが空に作られた、サーバは、この問題はライブ突っ込んだ引き起こす可能性があります(つまり、ヘッダ、アドレス、およびポートが付属しているので、UDPは、存在しない)
LEN(MSG)== 0 IF:続行
client.send(MSG)
1.辞書は、第一のヘッダ受信
header_dictのclient.recv =を(4)
#2取得辞書はヘッダ長解析し
dict_size = struct.unpack( 'I'、 header_dict)を[0]# 開梱時間がインデックス0されなければならない
# 3.データ辞書受信
dict_bytes = client.recv(dict_size)
dict_json = json.loads(dict_bytes.decode( 'UTF-8'))
辞書から情報を取得する。#4
recv_size = 0
real_data = B ''
位でなければならないし<終了したばかりされている可能性が最後の時間は、すなわちrecv_size = dict_jsonが、大したことは再び受信した場合、
変更された場合は#1 =を、最後に収穫し、まだ満足決意条件を持っているでしょう空で受信し、ラムは生きます
一方recv_size <dict_json.get( 'FILE_SIZE'):
データ= client.recv(1024)
real_data + =データ
recv_size + = LEN(データ)
の印刷(real_data.decode( 'GBK'))
`` `

** **エゴン办法解决方
https://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
https://www.cnblogs.com/gala/archive/2011/09/22/ 2184801.html
服务端
`Pythonの
ソケットインポート*から
インポートサブプロセス
インポート構造体
ip_port =( '127.0.0.1'、8080)
back_log = 5
BUFFER_SIZE = 1024

tcp_server =ソケット(AF_INET、SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

真の中:
CONN、ADDR = tcp_server.accept()
印刷( '新しいクライアントリンク'、addrは)
しばらく真:
#は閉じ
試して:
CMD = conn.recv(BUFFER_SIZE)
IFないCMD:BREAKの
印刷(」顧客の領収書「コマンドの終わり、CMD)

実行#、コマンド操作の結果得られたcmd_res
RES =のsubprocess.Popen(cmd.decode( 'UTF-8')、殻= Trueを、
標準エラー= subprocess.PIPE、
STDOUT = subprocess.PIPE、
STDIN = subprocess.PIPE)
ERR res.stderr.read =()
IF ERR:
cmd_res ERR =
他:
cmd_res = res.stdout.read()

#髪
IFないcmd_res:
cmd_resの= '正常に実行された' .encode( 'GBK')

lenは=長さ(cmd_res)
与えられたフォーマット(FMT)によると、データは文字列の中にカプセル化されている#
直接である文字列に#整数
DATA_LENGTH = struct.pack(「I」、長さ)
#スティックパッケージは、ここでは関係ありません。クライアントは、4バイトの代表的な長さを知っている
conn.send(DATA_LENGTH)
conn.send(cmd_res)を

eと例外を除いて:
印刷(e)の
ブレーク
`` `
客户端
` `` Pythonの
ソケットのインポート*のから
の輸入構造体
functoolsからの部分的なインポート
ip_port =( '127.0.0.1'、8080)
back_log = 5
BUFFER_SIZE = 1024

tcp_client =ソケット(AF_INET、SOCK_STREAM)
tcp_client.connect(ip_port)

:真しばらく
.strip():CMD =入力( '>>')
cmdをされていない場合:継続
休憩:CMD ==は'終了'場合

tcp_client.send(cmd.encode( 'UTF-8'))


溶液粘度パケット#1
のデータ#1 int型、バイナリ標準長が4であるので、最初の4つは、受信
length_data = tcp_client.recv(4)
テイク[0]は最初の値は、解決されている「INT」タイプの
長さ=構造体を。 ( 'I'、length_data)を解凍 [0]

= recv_msg「」に参加(ITER(部分(tcp_client.recv、BUFFER_SIZE)、B.「」))
これは、いくつかのための問題であり、研究と研究下にあり得る保存機能欠落しているべきである
(1.tcp_client.recv:#分析を)関数は、情報、最大BUFFER_SIZEバイト、受信
tcp_client.recvする一部の機能を使用して#を()関数は、第1のパラメータBUFFER_SIZE固定されている
一部の機能はイテラブルに、ITERを(使用#2)
#3。メモリは、カーネルモードからの各データを取得し、そして'「tcp_client.recvコンテンツBまで」にスプライス
プリント(「コマンド実行結果が、recv_msg.decode( 『GBK』) )

tcp_client.close()
`` `
サプリメント:`
`` Pythonの
#it​​er(オブジェクト、センチネル)
#パラメータを1つだけ書く:最初のものはイテレータになり
#は、第二引数を追加:センチネルを、センチネル反復コンテンツがすぐに停止下

#部分関数:固定パラメータの最初の機能
functoolsから、部分インポート
DEF(X、Y)を追加:
リターンX + Yの
位に渡される最初のパラメータを追加、追加の機能を指定する
(1加算)FUNC =の部分を
印刷します(FUNC(1))#2
印刷(FUNC(1))。3#
`` `
パック(FMT、V1、V2、...)指定されたフォーマット(FMT)によれば、データは、実際には(文字列にカプセル化されバイトストリームCの構造と同様である)
アンパック(FMT、String)をバイトストリーム解析文字列、所定のフォーマットに従って解析戻る(FMT)タプル

すべてのデータが送信されるまで送信をもとにsendallソケットは、()、、デッドサイクルセンドあります。
そして、データが歪んをスローするように、リアセンブリをフラグメント化しますが大きすぎる送信、好ましくは最大伝送単位MTU 1500バイトカードを8K(8096bytes)の最大値を送信


**サブプロセス
https://www.cnblogs.com/linhaifeng /articles/6129246.html#_label9

**回避通信サイクル所与の
サービスconn.recv()の最後に1を
空の場合に使用:CONN溶液は、メッセージサーバが空の無限ループ受信した折れ起因
通信サイクルで2サーバ治療のクライアント・プロセスは、(リモートホストに強制的に既存の接続によって閉じ)エラーが発生して異常中断された
:試してみる
#通信サイクル
:E AS例外を除いて
印刷(E)
ブレーク

クライアントがサーバにアップロード-転送ファイル
`` ` Pythonの
インポートソケット
インポートOS
のインポートのJSON
のインポート構造体

サーバ= socket.socket()
server.bind(( '127.0.0.1'、8080))
server.listen(5)

真つつ:
コネティカット、ADDR = server.accept()
真中:
試みは:
header_len conn.recv =(4)
ヘッダが解析辞書
header_len struct.unpack =( 'I'は、header_len)を[0]
長い辞書データ受信
header_dicをconn.recv =(header_len)
real_dic =のjson.loads(header_dic.decode( 'UTF-8'))
は、データ長取得
TOTAL_SIZE = real_dic.get( 'FILE_SIZE')
ループは受信したファイル書き込み
recv_size = 0を
開くとF AS(real_dic.get( 'file_nameに')、 'WB'):
しばらくrecv_size <TOTAL_SIZE:
データ= conn.recv(1024)
f.write(データ)
recv_size + = LEN(データ)
を印刷(「成功したアップロード「)
E ConnectionResetError AS除い:
印刷(E)
BREAK
コネティカット。近いです()
`` `

クライアント
`` `Pythonの
インポートソケット
インポートJSON
インポートのOS
インポート構造体

クライアント= socket.socket()
client.connect(( '127.0.0.1'、8080))

真しばらく:
#を通じて映画リストサイクルを取得
MOVIE_DIR = r'D:\ pythonのフルタイム10ビデオの\ day25 \ビデオ「
movie_list = os.listdir(MOVIE_DIR)
印刷(movie_list)
私のために、映画列挙中(movie_list、1) :
印刷(I、動画)
#ユーザが選択した
選択肢= INPUTを( 'してください選択ムービー>>>にアップロード:')
があるか否かを判定するデジタル
のiF choice.isdigit():
デジタルint型に#文字列
の選択= INT(選択) - 1つの。
#は、選択されたユーザは範囲のリスト内にあるか否かを判断する
選択範囲内(0、LEN(movie_list))IF:
は、取得ユーザがファイルパスアップロードしたい
パス= movie_list [選択]
#スプライシングファイルの絶対パスを
FILE_PATH = OS .path.join(MOVIE_DIR、パス)
#ファイルサイズ得る
FILE_SIZEを= os.path.getsize(FILE_PATH)
辞書を定義
{= RES_Dを
'FILE_NAME': 'セクシーディーラーオンラインライセンス.MP4'、
'FILE_SIZE':FILE_SIZE、
'MSG': '身体への注意、栄養エクスプレスをたくさん飲む'
}
#シリアライゼーション辞書
json_d = json.dumps(RES_D)
json_bytes = json_d.encode( 'UTF-8')

#まず生産辞書フォーマットヘッダ
ヘッダstruct.pack =( 'I'、LEN(json_bytes))
#2の送信辞書ヘッダ
client.send(ヘッダ)
#3再発辞書
client.send(json_bytes)
4.再送データファイル(ファイルのオープンループ送信)
:オープン(FILE_PATH「RB」)F ASで
:ラインF中のため
client.send(ライン)
他:
印刷(「ない範囲で、」)
他:
印刷( '番号は、「MUST BE)
`` `

おすすめ

転載: www.cnblogs.com/lishuaing/p/11354060.html