table of Contents
Stick package problem
TCP protocol will be sticky packets of data during transmission problem
Talk about the difference between TCP and UDP, data transfer protocols are no good or bad to say, but different application requirements which may be a better choice protocol
TCP: suitable for transmitting large quantities, the need to establish a connection, there will be sticky bag, sticker pack can solve the problem, determine the length of the incoming, receive the same length can be guaranteed a one-time transfer complete
UDP: suitable for a small amount of data transmission, no stick package, no connection, one-time transmission, the next is the new data, the drawbacks is that data loss, insecurity
QQ is what protocol to use it? In theory should be able to use UDP protocol, but the actual use the TCP protocol, which is an issue left over from history, can still remember what words we enter the QQ-time input of restrictions? It is to require the sending and receiving the data length is the same.
Reasons for the formation of stick package
1. The two data is very small, then a short interval of time and
2. The data is too large, could not finish a take, we will take the next big data
Stick package to solve the problem
== Before data transfer, a data transfer size, the size of the data must have a fixed length ==
# TCP 解决粘包问题 附带处理了一下
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...')
# 连接循环
while True:
conn, client_address = server.accept()
print(client_address)
# 通信循环
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: # 连接循环时出现的中断
break
conn.close()
# 客户端
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'))
Based on UDP socket socket programming
Connectionless UDP
# UDP服务端 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客户端 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)
And TCP is about the same, calling the function is the same, but the specific representation method name is not the same, because the connectionless UDP, TCP and UDP sendto of the send, sendto on UDP is to refer directly to the address
Based on socket socket programming socketserver achieve concurrency
Let the server and multiple clients simultaneously connect before we write there is a police station five phone only one person, now written five phone five people
# 同一时刻有多个人在接听 import socketserver import subprocess import struct class MyHandler(socketserver.BaseRequestHandler): # 通信循环 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 # 使用socketserver的连接循环(并发),但是使用了自己的通信循环 # myhandler = MyHandler() if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True) print('start...') server.serve_forever()