この記事では主に、TCP スティッキー パケットの問題を解決する方法について説明します。1 つ目は、コンテンツ サイズとコンテンツをそれぞれ 2 回の通信で転送する方法、2 つ目は、コンテンツ サイズとコンテンツを 1 回の通信で直接転送する方法です。もっと詳しく知りたい友達は、この記事を詳しく読んでみてください。お役に立てれば幸いです。
原理分析図:
##1 ソケット通信プロセスを図に示します。まず、クライアントが send() メソッドを通じてクライアント コンピューターのカーネル領域にコンテンツを送信し、次にオペレーティング システムがコンテンツを送信します。基盤となるパスを介してサーバーのカーネル領域にデータを送信し、サーバー プログラムは、recv() メソッドを通じてサーバー コンピューターのカーネル領域からデータを取得します。
2 つまり、sendメソッドはサーバーにコンテンツを直接送信するのではなく、recvメソッドはクライアントからサーバーのプログラムメモリに送信されたコンテンツを直接受信するのではなく、自マシンのカーネルを動作させるということが分かります。 。 地区。
受信者は、受信が完了するまでにどれだけのデータを受信すべきかを知らないため、スティッキー パケットが発生します。
パート 3: 上記 2 つの問題を解決する方法粘着バッグ現象? アイデア 1: 最初のスティッキー パケットの生成方法では、2 つの send() で recv() を直接使用して、連続送信を防ぐことができます。コードを表示する必要はありません。 アイデア 2:スティッキー パケットは受信者の無制限受信によって発生するため、送信者はデータを送信する前に受信者にコンテンツのサイズを通知できます。コード例は次のとおりです。
方法 1: コンテンツ サイズとコンテンツを 2 つの通信でそれぞれ渡します
サーバー側コード:
# __author__:Kelvin # date:2019/4/28 21:36 from socket import * import subprocess server = socket(AF_INET, SOCK_STREAM) server.bind(("127.0.0.1", 8000)) server.listen(5) while True: conn, addr = server.accept() print("创建了一个新的连接!") while True: try: data = conn.recv(1024) if not data: break res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() if err: cmd_msg = err else: cmd_msg = res.stdout.read() if not cmd_msg: cmd_msg = "action success!".encode("gbk") length = len(cmd_msg) conn.send(str(length).encode("utf-8")) conn.recv(1024) conn.send(cmd_msg) except Exception as e: print(e) break
クライアント側コード:
# __author__:Kelvin # date:2019/4/28 21:36 from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(("127.0.0.1", 8000)) while True: inp = input(">>:") if not inp: continue if inp == "quit": break client.send(inp.encode("utf-8")) length = int(client.recv(1024).decode("utf-8")) client.send("ready!".encode("utf-8")) lengthed = 0 cmd_msg = b"" while lengthed < length: cmd_msg += client.recv(1024) lengthed = len(cmd_msg) print(cmd_msg.decode("gbk"))
## 方法 2: 1 回の通信でコンテンツのサイズと内容を直接送信する
##サーバー側: # __author__:Kelvin
# date:2019/4/28 21:36
from socket import *
import subprocess
import struct
server = socket(AF_INET, SOCK_STREAM)
server.bind(("127.0.0.1", 8000))
server.listen(5)
while True:
conn, addr = server.accept()
print("创建了一个新的连接!")
while True:
try:
data = conn.recv(1024)
if not data: break
res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
err = res.stderr.read()
if err:
cmd_msg = err
else:
cmd_msg = res.stdout.read()
if not cmd_msg: cmd_msg = "action success!".encode("gbk")
length = len(cmd_msg)
conn.send(struct.pack("i", length))
conn.send(cmd_msg)
except Exception as e:
print(e)
break
# __author__:Kelvin
# date:2019/4/28 21:36
from socket import *
import struct
client = socket(AF_INET, SOCK_STREAM)
client.connect(("127.0.0.1", 8000))
while True:
inp = input(">>:")
if not inp: continue
if inp == "quit": break
client.send(inp.encode("utf-8"))
length = struct.unpack("i",client.recv(4))[0]
lengthed = 0
cmd_msg = b""
while lengthed < length:
cmd_msg += client.recv(1024)
lengthed = len(cmd_msg)
print(cmd_msg.decode("gbk"))
以上がTCP スティッキー パケットの問題を解決する 2 つの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。