python Sticking Problem and socket Socket Programming Detailed Explanation

  • 2021-07-06 11:14:40
  • OfStack

Pack sticking problem

TCP protocol will have the problem of data packet sticking in the transmission process

Talk about the difference between TCP and UDP. They are all data transmission protocols. There is no good or bad, but different application requirements may better choose which protocol

TCP: Suitable for a large number of transmissions, the need to establish a connection, there will be a packet sticking problem, the packet sticking problem can be solved, determine the incoming length, receive the same length can ensure the completion of one-time transmission

UDP: Suitable for transmission of small amount of data, no sticky packets, no connection, one-time transmission, the next one is new data, the drawback is data loss, insecurity

What protocol does QQ use? It should be possible to use UDP protocol, but actually use TCP protocol, which is a problem left over from history. Can we remember that there is a limit on the number of words in the content of QQ1 secondary input? That is, the length of data sent and received is 1.

Reasons for forming sticky bags

1. The two data are very small, and then the interval is short

2. The data is too big to be taken once, and this big data will be taken next time

Solve the problem of sticky package

= = Before transferring data, transfer 1 data size, and the data size must have a fixed length = =


# TCP  Solve the problem of sticky package   Incidentally processed 1 Under 
import socket
import struct
import subprocess
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8000))
server.listen(5)
print('start...')
#  Connection loop 
while True:
conn, client_address = server.accept()
print(client_address)
#  Communication loop 
while True:
try:
cmd = conn.recv(1024)
print(cmd)
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read()
count_len = len(stdout) + len(stderr)
guding_bytes = struct.pack('i', count_len)
conn.send(guding_bytes) # 4
conn.send(stderr + stdout)
except ConnectionResetError: #  Interrupt when connecting loop 
break
conn.close()

#  Client 
mport struct
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
# cmd = input('please enter your cmd you want:')
cmd = 'dir'
client.send(cmd.encode('utf8'))
guding_bytes = client.recv(4)
count_len = struct.unpack('i', guding_bytes)[0]
data = client.recv(count_len)
print(data.decode('gbk'))

socket socket programming based on UDP protocol

UDP Connectionless


# UDP Server side 
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8000))
print('start...')
while True:
data, client_addr = server.recvfrom(1024)
print(client_addr)
print(data)
server.sendto(data.upper(), client_addr)

# UDP Client 
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = input('please enter your msg:')
client.sendto(msg.encode('utf8'), ('127.0.0.1', 8000))
data = client.recvfrom(1024)
print(data)

It is similar to TCP, and the function of calling is one kind, but the specific representation method of method name is not one kind, because UDP has no connection, sendto of UDP and send of UDP, that is, sendto of UDP should directly refer to the address

Realization of concurrent socket socket programming based on socketserver

Let the server connect with multiple clients at the same time. In the past, we wrote that there were 5 telephones in a police station and only 1 person. Now we write 5 telephones and 5 people


#  Same as 1 There are many people answering at all times 
import socketserver
import subprocess 
import struct
class MyHandler(socketserver.BaseRequestHandler):
#  Communication loop 
def handle(self):
while True:
try:
cmd = self.request.recv(1024)
print(cmd)
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell = True,
stderr = subprocess.PIPE,
stdout = subprocess.PIPE)
stdout = pipeline.stdout.read()
stderr = pipeline.stderr.read()
count_len = len(stderr) + len(stdout)
guding_bytes = struct.pack('i', count_len)
self.request.send(guding_bytes) # 4
self.request.send(stderr + stdout)
except ConnectionResetError:
break
#  Use socketserver Connection loop of ( Concurrent ), But uses its own communication loop 
# myhandler = MyHandler()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True)
print('start...')
server.serve_forever()

Related articles: