First, what is sticky bag
1. Note: Only TCP has a sticky packet phenomenon, UDP will never stick packets
2. The so-called sticky packet problem is mainly because the receiver does not know the boundary between the message, do not know how many bytes of data extracted at once.
Two, two kinds of cases will occur sticky bag.
1. Send data time interval is very short, the data is very small, to join together to produce sticky bag
1 fromSocketImport*2 Import Time3Phone=socket (af_inet,sock_stream)4Phone.connect (('127.0.0.1', 8080))5 6Phone.send ('HelloWorld'. Encode ('Utf-8'))7Phone.send ('Egon'. Encode ('Utf-8'))
Client
2. The receiver does not receive the buffer in time packets, resulting in multiple packets received (the client sent a piece of data, the server only received a small portion of the service end of the next time, or from the buffer to take the last remaining data, resulting in sticky packets)
fromSocketImport*ImportTimephone=socket (Af_inet,sock_stream) phone.connect (('127.0.0.1', 8080)) Phone.send ('HelloWorld'. Encode ('Utf-8')) Time.sleep (5) Phone.send ('Egon'. Encode ('Utf-8'))
Client
fromSocketImport*Phone=socket (af_inet,sock_stream) phone.setsockopt (sol_socket,so_reuseaddr,1) Phone.bind ('127.0.0.1', 8080)) Phone.listen (5) conn,client_addr=phone.accept () data1=CONN.RECV (8)Print('data1:', data1) data2=CONN.RECV (20)Print('data2:', data2) data3=CONN.RECV (20)Print('data3:', data3)#Results#data1:b ' Hellowor '#data2:b ' ld '#data3:b ' Egon '
Service Side
Three
What happens when a package is split
When the length of the sending buffer is greater than the MTU of the NIC, TCP splits the sent data into a few data packets sent out.
Supplementary question one: Why TCP is reliable transmission, UDP is unreliable transmission
TCP-based data transfer please refer to my other article Http://www.cnblogs.com/linhaifeng/articles/5937962.html,tcp at the time of data transmission, the sending end sends the data to its own cache first, Then the Protocol control sends the data in the cache to the peer, returns a ack=1 to the end, the sender cleans up the data in the cache, returns ack=0 to the end, and then sends the data back, so TCP is reliable
While UDP sends data, the peer does not return a confirmation message, and therefore unreliable
Supplementary Question II: send (Byte stream) and recv (1024) and Sendall
The 1024 specified in recv means that 1024 bytes of data are taken out of the cache at a time.
The byte stream of send is put into the cache first, then the cache content is sent to the peer by the Protocol control, if the byte stream to be sent is larger than the buffer space, then the data is lost, and the data will be called by Sendall.
Four, the solution of the low ratio of adhesive package processing method
1 ImportSocket2 Importsubprocess3 Importstruct4Phone=socket.socket (Socket.af_inet,socket. SOCK_STREAM)#buy a cell phone5Phone.setsockopt (socket. Sol_socket,socket. so_reuseaddr,1)#That 's it, in front of BIND plus6Phone.bind (('127.0.0.1', 8082))#Binding Mobile Card7Phone.listen (5)#Boot8 9 Print('starting ...')Ten whileTrue:#Link Loops OneConn,client_addr=phone.accept ()#and so on the phone (link, the client's IP and the port consisting of tuples) A Print('-------->', CONN,CLIENT_ADDR) - #collect, send a message - whileTrue:#Communication Cycle the Try: -CMD=CONN.RECV (1024) - if notCmd: Break #for Linux - #execute cmd command, get cmd result, result should be bytes type + #.... -res = subprocess. Popen (Cmd.decode ('Utf-8'), shell=True, +stdout=subprocess. PIPE, AStderr=subprocess. PIPE) atstdout=Res.stdout.read () -Stderr=Res.stderr.read () - #first outgoing header (turns into a fixed-length bytes type) -Header = Struct.pack ('I', Len (stdout) +Len (stderr)) - conn.send (header) - #the result of sending the command again 5 in Conn.send (stdout) - conn.send (stderr) to exceptException: + Break -Conn.close ()#Hang up the phone thePhone.close ()#turn off the machine
Service Side
1 ImportSocket2 Importstruct3Phone=socket.socket (Socket.af_inet,socket. SOCK_STREAM)#buy a cell phone4Phone.connect (('127.0.0.1', 8082))#Binding Mobile Card5 #send and receive messages6 whileTrue:7Cmd=input ('>>:'). Strip ()8 if notCmd:Continue9Phone.send (Cmd.encode ('Utf-8'))Ten #Receive headers First OneHEADER_STRUCT=PHONE.RECV (4) AUnpack_res = Struct.unpack ('I', Header_struct) -Total_size=Unpack_res[0] - #Collect Data again theRecv_size=0#10241=10240+1 -Total_data=b"' - whileRecv_size <total_size: -RECV_DATA=PHONE.RECV (1024) +recv_size+=Len (recv_data) -total_data+=Recv_data + Print(Total_data.decode ('GBK')) APhone.close ()
Client
python-day30--Sticky Bag