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()