Causes of sticky packs:
Continuous send multiple small data, there will be sticky phenomenon, which is caused by the TCP protocol optimization algorithm
When a data is sent that exceeds the maximum range of this receive, the remaining data is left to be received at the next receive
The phenomenon of sticky bag:
import Socketsk = Socket.socket () Sk.bind (( " 127.0.0.1 ", 8090)) Sk.listen () conn,addr = sk.accept () ret = CONN.RECV (2) # Span style= "COLOR: #008000" > Here first receives a two-byte content Ret2 = Conn.recv (Ten) # print (ret) print (Ret2) Conn.close () sk.close ()
Import= socket.socket () sk.connect('127.0.0.1', 8090) Sk.send (b'helloeve') # sends a byte with a length of 8 here Sk.close ()
B ' he '
B ' Lloeve '
You can see that the received content is separated.
import Socketsk = Socket.socket () Sk.bind (( " 127.0.0.1 ", 8090)) Sk.listen () conn,addr = sk.accept () Ret1 = CONN.RECV (+) # received two times here print (RET1) Ret2 = conn.recv (12 print (Ret2) Conn.close () sk.close ()
Import= socket.socket () sk.connect('127.0.0.1', 8090) Sk.send (b'hello') # Here we send two consecutive data sk.send (b' Eve ') sk.close ()
B ' Helloeve '
B ' '
Originally expected to receive two content was synthesized one received
This is the sticky bag.
Therefore, the root cause of the sticky packet is that the receiver does not know the size of the data received this time, will occur sticky packets
How to solve the sticky bag
Actually know what is the reason for the sticky bag, then, as long as the data before each send, tell the other person how much data I want to send the line
ImportSocketsk=socket.socket () Sk.bind ('127.0.0.1', 8080) ) Sk.listen () conn,addr=sk.accept () whileTrue:cmd= Input ('>>>') ifcmd = ='Q': conn.send (b'Q') Breakconn.send (Cmd.encode ('GBK') Num= Conn.recv (1024x768). Decode ('Utf-8')#assigns the length of the received to a variableConn.send (b'OK')#want the client to send a message indicating that the length has been receivedres = CONN.RECV (int (num)). Decode ('GBK')#The received length value to the number of bytes received Print(RES) conn.close () sk.close ()
ImportSocketImportSubprocess#calling the Subprocess moduleSK =socket.socket () Sk.connect ('127.0.0.1', 8080)) whileTrue:cmd= Sk.recv (1024x768). Decode ('GBK') ifcmd = ='Q': BreakRes= subprocess. Popen (cmd,shell=True, stdout=subprocess. PIPE,#put the stuff in the pipe .Stderr=subprocess. PIPE)#Pipe PipingStd_out = Res.stdout.read ()#assign the data in the pipeline to a variableStd_err = Res.stderr.read ()#because everything in the pipeline can only be taken once .Sk.send (str (std_out) +len (Std_err)). Encode ('Utf-8'))#send the length of the measurement to the serverSK.RECV (1024)#receive feedback from the service sideSk.send (Std_out)#send the data pastsk.send (Std_err) sk.close ()
So each time before sending the number of bytes of data sent to the secondary, so that the other side of the receiver will not occur sticky packet phenomenon
However, although it is not sticky, each send requires an interaction that increases the work of the Code
How can you solve these problems in one interaction?
It's going to take
struct MODULE
A struct module can turn a type into a fixed-length bytes
We just need to use int this time.
ImportstructImportSocketsk=socket.socket () Sk.bind ('127.0.0.1', 8080) ) Sk.listen () conn,addr=sk.accept () whileTrue:cmd= Input ('>>>') ifcmd = ='Q': conn.send (b'Q') Breakconn.send (Cmd.encode ('GBK') Num= CONN.RECV (4)#to accept the client's coming .num = Struct.unpack ('I', num) [0]#To get the number of bytes in reverseres = CONN.RECV (int (num)). Decode ('GBK')#Pass the number of bytes to the receiving end when the parameter Print(RES) conn.close () sk.close ()
Importstruct#the struct module needs to be used .ImportSocketImportSubprocesssk=socket.socket () Sk.connect ('127.0.0.1', 8080)) whileTrue:cmd= Sk.recv (1024x768). Decode ('GBK') ifcmd = ='Q': BreakRes= subprocess. Popen (cmd,shell=True, stdout=subprocess. PIPE, stderr=subprocess. PIPE) Std_out=res.stdout.read () Std_err=res.stderr.read () len_num= Len (std_out) +len (Std_err)#assigns the calculated number of bytes to a variablenum_by = Struct.pack ('I', Len_num)#the number of bytes in the Strect module is converted to a length of 4 bytesSk.send (num_by)#then send it to the serversk.send (std_out) sk.send (Std_err) sk.close ()
All data transmitted over the network is called a packet
All data in the packet is called a message.
There's more than your data in the message, and the IP address, MAC address port number.
All messages have headers.
Python Sticky bag