In diesem Artikel geht es hauptsächlich darum, wie das TCP-Sticky-Problem gelöst werden kann. Das erste besteht darin, die Inhaltsgröße und den Inhalt in zwei Kommunikationen zu übertragen. Freunde, die mehr wissen möchten, können diesen Artikel ausführlich lesen. Ich hoffe, er wird Ihnen hilfreich sein.
Prinzipanalysediagramm:
1 Der Socket-Kommunikationsprozess ist wie in der Abbildung dargestellt: Zuerst sendet der Client den Inhalt über die send()-Methode an den Kernelbereich des Clientcomputers, und dann sendet das Betriebssystem den Inhalt Inhalte werden über den zugrunde liegenden Pfad in den Kernelbereich des Servers übertragen. Anschließend ruft das Serverprogramm die Daten über die recv()-Methode aus dem Kernelbereich des Servercomputers ab.
2 Daher können wir verstehen, dass die Sendemethode den Inhalt nicht direkt an den Server sendet und die Recv-Methode den vom Client gesendeten Inhalt nicht direkt in den Serverprogrammspeicher empfängt, sondern ihren eigenen Kernel betreibt Maschine.
1 1: Beim kontinuierlichen Senden von Daten. Aufgrund der Durch den Nagle-Algorithmus des TCP-Protokolls werden kleinere Inhalte in große Inhalte gespleißt und sofort an den Server gesendet, wodurch Sticky-Pakete entstehen. 2 3 2: Wenn der gesendete Inhalt groß ist, liegt dies an der Methode recv (buffer_size). serverseitig Die buffer_size ist klein und kann nicht den gesamten Inhalt auf einmal empfangen. Wenn die nächste Anforderung eintrifft, ist der empfangene Inhalt daher immer noch der Inhalt, der beim letzten Mal nicht vollständig empfangen wurde, was das Sticky-Phänomen verursacht.
Das heißt: Der Empfänger weiß nicht, wie viele Daten er empfangen soll, bevor er vollständig empfangen wird, was zu Sticky-Paketen führt.
Verwandte Tutorials: TCP/IP-Video-Tutorial
Idee 1: Für die erste Sticky-Packet-Generierungsmethode können Sie recv() direkt in zwei send()s verwenden, um ein kontinuierliches Senden zu verhindern. Es ist nicht erforderlich, den Code anzuzeigen.
Idee 2: Da Sticky Packets durch den unbegrenzten Empfang des Empfängers verursacht werden, kann der Sender den Empfänger vor dem Senden der Daten über die Größe des Inhalts informieren. Das Codebeispiel lautet wie folgt:
Methode 1: Übergeben Sie die Inhaltsgröße und den Inhalt jeweils in zwei Kommunikationen
Servercode:
# __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
Client-Code:
# __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"))
Methode 2: Inhaltsgröße und Inhalt direkt in einer Kommunikation übertragen
Serverseite:
# __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
Kunde:
# __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"))
Beide der beiden oben genannten Methoden können das Sticky-Problem lösen.
Das obige ist der detaillierte Inhalt vonZwei Möglichkeiten, das Problem der TCP-Sticky-Pakete zu lösen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!