day37高度なネットワークプログラミング

01リモート実行コマンド
サーバーを実装するためのtcpプロトコルに基づく
#サーバーは2つの特性を満たす必要があります:
#1、常に外部にサービスを提供する
#2、同時に複数のクライアントにサービスを提供するソケットインポートから
サブプロセス
をインポートする*

server = socket(AF_INET、SOCK_STREAM)
server.setsockopt(SOL_SOCKET、SO_REUSEADDR、1)#それだけです、バインドする前に
server.bind(( '127.0.0.1'、8082))
server.listen(5)を追加します

#服务端应做两事
#最初に:ボード接続プールからリンク要求を周期的に取り出し、双方向リンクを確立し、リンクオブジェクト
取得しますTrue:
conn、client_addr = server.accept()

#2番目のこと:リンクオブジェクトを取得して通信します
True:
試してください:
cmd = conn.recv(1024)
if len(cmd)== 0:break
obj = subprocess.Popen(cmd.decode( 'utf -8 ')、
shell = True、
stdout = subprocess.PIPE、
stderr = subprocess.PIPE

stdout_res = obj.stdout.read()
stderr_res = obj.stderr.read()
print(len(stdout_res)+ len(stderr_res))
#conn.send(stdout_res + stderr_res)#???
conn.send(stdout_res)
conn.send(stderr_res)

#open( "1.mp4"、mode = 'rb')をfとして使用

#fの行#conn.send(line)
例外を除く:
break
conn.close()

クライアント:
ソケットインポートから*

client = socket(AF_INET、SOCK_STREAM)
client.connect(( '127.0.0.1'、8082))

while True:
cmd = input( 'Please enter the command >>:')。strip()
if len(cmd)== 0:continue
client.send(cmd.encode( 'utf-8'))

#スティッキーパケットの問題を解決する方法:
#1.データの合計サイズを取得しますtotal_size
#2. recv_size = 0、循環的に受信し、受信するたびに、recv_size + =受信の長さ
#3. recv_size = total_sizeになるまで、サイクルを終了します
cmd_res =クライアント。 recv(1024)#この受信、最大受信は
1024Bytes印刷(cmd_res.decode( 'utf-8'))#強調:Windowsシステムのgbk


#スティッキーパッケージの問題が原因
#1. tcpはストリーミングプロトコルであり、データは水の境界のようにくっついて、境界を区別しない
#2.データが収集されて没収され、残留物があり、次の結果が混乱する

#解決策の中核的な方法は次のとおりです。毎回きれいにして、残留物を残さない

 

02 udpプロトコルにスティッキパケットの問題はありません

サーバー:
ソケットのインポート

server = socket.socket(socket.AF_INET、socket.SOCK_DGRAM)
server.bind(( '127.0.0.1'、8080))
res1 = server.recvfrom(2)#b "hello"
print(res1)
res2 = server.recvfrom (3)
#b "world" print(res2)

server.close()

クライアント:
インポートソケット

client = socket.socket(socket.AF_INET、socket.SOCK_DGRAM)
client.sendto(b'hello '、(' 127.0.0.1 '、8080))
client.sendto(b'world'、( '127.0.0.1'、8080 ))

client.close()


粘着性の問題解決する03のパッケージ
:サーバー
2つの特性満たさなければならない#サーバーを:
#1を、サービスを提供してきました
、同時に複数のクライアントサービス提供#2、
インポートサブプロセス
のインポート構造体
ソケットからのインポートを*

server = socket(AF_INET、SOCK_STREAM)
server.setsockopt(SOL_SOCKET、SO_REUSEADDR、1)#以上です。バインドする前に
server.bind(( '127.0.0.1'、8083))
server.listen(5)を追加します

#服务端应做两事
#最初に:ボード接続プールからリンク要求を周期的に取り出し、双方向リンクを確立し、リンクオブジェクト
取得しますTrue:
conn、client_addr = server.accept()

#2番目のこと:リンクオブジェクトを取得して通信します
True:
試してください:
cmd = conn.recv(1024)
if len(cmd)== 0:break
obj = subprocess.Popen(cmd.decode( 'utf -8 ')、
shell = True、
stdout = subprocess.PIPE、
stderr = subprocess.PIPE

stdout_res = obj.stdout.read()
stderr_res = obj.stderr.read()
total_size = len(stdout_res)+ len(stderr_res)

#1、ヘッダー情報を送信(固定長バイト):データの説明情報
#int->固定長バイト
ヘッダー= struct.pack( 'i'、total_size)
conn.send(ヘッダー)

#2、次に実際のデータを送信
conn.send(stdout_res)
conn.send(stderr_res)

例外を除いて:
break
conn.close()

クライアント:ソケットインポートから
構造体
をインポート*

client = socket(AF_INET、SOCK_STREAM)
client.connect(( '127.0.0.1'、8083))

while True:
cmd = input( 'Please enter the command >>:')。strip()
if len(cmd)== 0:continue
client.send(cmd.encode( 'utf-8'))

#スティッキーパケットの問題を解決するには:
#最初に、固定長ヘッダーを収集します:データの合計サイズを含むデータの説明情報を解析しますtotal_size
header
= client.recv(4)total_size = struct.unpack( 'i'、header) [0]

#2.解析された記述情報に従って実データを受信します
。2. recv_size = 0、サイクリック受信、受信されるたびに、recv_size + =受信の長さ
#3. recv_size = total_sizeまで、サイクルを終了します
recv_size = 0
while recv_size <total_size :
recv_data = client.recv(1024)
recv_size + = len(recv_data)
print(recv_data.decode( 'utf-8')、end = '')
else:
print()


#スティッキーパッケージの問題が原因
#1. tcpはストリーミングプロトコルであり、データは水の境界のようにくっついて、境界を区別しない
#2.データが収集されて没収され、残留物があり、次の結果が混乱する

#解決策の中核的な方法は次のとおりです。毎回きれいにして、残留物を残さない


04粘着性パッケージの問題を解決する(Ultimate Edition)

サーバー:
#サーバーは2つの特性を満たす必要があります:
#1.常に外部にサービスを提供します
#2.複数のクライアントに同時にサービスを提供します
import importサブプロセス
import struct
import json
from socket import *

server = socket(AF_INET、SOCK_STREAM)
server.setsockopt(SOL_SOCKET、SO_REUSEADDR、1)#以上です。バインドする前に
server.bind(( '127.0.0.1'、8083))
server.listen(5)を追加します

#服务端应做两事
#最初に:ボード接続プールからリンク要求を周期的に取り出し、双方向リンクを確立し、リンクオブジェクト
取得しますTrue:
conn、client_addr = server.accept()

#2番目のこと:リンクオブジェクトを取得して通信します
True:
試してください:
cmd = conn.recv(1024)
if len(cmd)== 0:break
obj = subprocess.Popen(cmd.decode( 'utf -8 ')、
shell = True、
stdout = subprocess.PIPE、
stderr = subprocess.PIPE

stdout_res = obj.stdout.read()
stderr_res = obj.stderr.read()
total_size = len(stdout_res)+ len(stderr_res)

#1、制作头
header_dic = {
"filename": "a.txt"、
"total_size":total_size、
"md5": "123123xi12ix12"
}

json_str = json.dumps(header_dic)
json_str_bytes = json_str.encode( 'utf-8')


#2、最初にヘッダーの長さを
x = struct.pack( 'i'、len(json_str_bytes))に
送信しますconn.send(x)

#3.ヘッダー情報を送信する
conn.send(json_str_bytes)
#4.実際のデータを送信する
conn.send(stdout_res)
conn.send(stderr_res)

例外を除いて:
break
conn.close()

クライアント:
import struct
import json
from socket import *

client = socket(AF_INET、SOCK_STREAM)
client.connect(( '127.0.0.1'、8083))

while True:
cmd = input( 'Please enter the command >>:')。strip()
if len(cmd)== 0:continue
client.send(cmd.encode( 'utf-8'))

#レシーバー
#1. 4バイトから開始し、受信するヘッダーの長さを抽出します
x =
client.recv (4)header_len = struct.unpack( 'i'、x)[0]

#2、受信头、および解析
json_str_bytes = client.recv(header_len)
json_str = json_str_bytes.decode( 'utf-8')
header_dic = json.loads(json_str)
print(header_dic)
total_size = header_dic ["total_size"]

#3、受信真実的
データrecv_size = 0
while recv_size <total_size:
recv_data = client.recv(1024)
recv_size + = len(recv_data)
print(recv_data.decode( 'utf-8')、end = '')
else:
print ()


#スティッキーパッケージの問題が原因
#1. tcpはストリーミングプロトコルであり、データは水の境界のようにくっついて、境界を区別しない
#2.データが収集されて没収され、残留物があり、次の結果が混乱する

#解決策の中核的な方法は次のとおりです。毎回きれいにして、残留物を残さない


基本的な使用05 socketserverモジュール
プロトコルTCPの使用に基づいて
サーバー:
インポートSocketServer

クラスMyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
#如果tcp协议、self.request => conn
print(self.client_address)
while True:
try:
msg = self.request.recv(1024)
if len(msg )== 0:break
self.request.send(msg.upper())
例外を除いて:
break
self.request.close()

 

#服务端は2つのことを行う必要があります
#最初のこと:半接続プールからリンク要求を周期的に取り出し、双方向リンクを確立し、リンクオブジェクトを取得します
s = socketserver.ThreadingTCPServer(( '127.0.0.1'、8889)、MyRequestHandle )
s.serve_forever()
#は#while
True と同等です:
#conn、client_addr = server.accept()
#スレッドを開始します(conn、client_addr)

#2番目のこと:リンクオブジェクトを取得して通信する===>ハンドル

クライアント:
ソケットインポートから*

client = socket(AF_INET、SOCK_STREAM)
client.connect(( '127.0.0.1'、8889))

while True:
msg = input( '请输入命令>>:')。strip()
if len(msg)== 0:continue
client.send(msg.encode( 'utf-8'))

res = client.recv(1024)
print(res.decode( 'utf-8'))


udpプロトコルに基づく
サーバーを使用する
ソケットサーバーインポートする

クラスMyRequestHanlde(socketserver.BaseRequestHandler):
def handle(self):
client_data = self.request [0]
server = self.request [1]
client_address = self.client_address
print( '客户端発来的データ%s'%client_data)
server.sendto(client_data.upper()、client_address)


s = socketserver.ThreadingUDPServer(( "127.0.0.1"、8888)、MyRequestHanlde)
s.serve_forever()
#同等:リサイクルのみを担当#while
True:
#data、client_addr = server.recvfrom(1024)#start
aスレッドは後続の処理(データ、client_addr)

クライアント:
インポートソケット

client = socket.socket(socket.AF_INET、socket.SOCK_DGRAM)#ストリーミングプロトコル=》 tcpプロトコル

while True:
msg = input( '>>>:').strip()
client.sendto(msg.encode( 'utf-8')、( '115.29.65.16'、8888))
res = client.recvfrom(1024 )
印刷(解像度)

client.close()

おすすめ

転載: www.cnblogs.com/python--wang/p/12748259.html