Après avoir écouté le professeur Lin HaifengsockertserverRésumé de
Un.、Tout d'abord,socketserverIl existe deux grandes catégories de modules:
serverCatégorie(Résoudre les problèmes de liaison)EtrequestCatégorie(Résoudre les problèmes de communication)
1、serverCatégorie
2、requestCatégorie:
2.、 Je vais d'abord vous expliquer la base TCPDesockertserverUtilisation de base
Code du serveur:
import socketserver
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
print(self.request) # Si ouitcpAccord,self.request=>conn
print(self.client_address)
while True:
try:
msg=self.request.recv(1024)
if len(msg)==0:break
self.request.send(msg.upper())
except Exception:
break
self.request.close()
'''
s.serve_forever()=>équivalent au code suivant
while True:
conn,client_addr=server.accept()
Démarrer un thread(conn,client_addr)
'''
# Le serveur devrait faire deux choses
# 1、La première chose: Boucle pour extraire une demande de lien d'un pool de demi - liens et établir un lien bidirectionnel avec elle ,Obtenir l'objet lié
s = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MyRequestHandle)
s.serve_forever()
# 2、Obtenir l'objet lié,Cycle de communication avec==>handle
Client1Code:
from socket import *
import struct
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8888))
while True:
msg=input('Veuillez saisir la commande>>>>').strip()
if len(msg)==0:
continue
client.send((msg.encode('utf-8')))
recv_data=client.recv(1024)
print(recv_data.decode('utf-8'))
Client2Code:
from socket import *
import struct
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8888))
while True:
msg=input('Veuillez saisir la commande>>>>').strip()
if len(msg)==0:
continue
client.send((msg.encode('utf-8')))
recv_data=client.recv(1024)
print(recv_data.decode('utf-8'))
Résultats des opérations:
# Résultats du serveur :
<socket.socket fd=812, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8888), raddr=('127.0.0.1', 63110)>
('127.0.0.1', 63110)
<socket.socket fd=692, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8888), raddr=('127.0.0.1', 63115)>
('127.0.0.1', 63115)
# Client1Résultats:
Veuillez saisir la commande>>>>asasa
ASASA
Veuillez saisir la commande>>>>ds
DS
Veuillez saisir la commande>>>>
# Client2Résultats:
Veuillez saisir la commande>>>>asas
ASAS
Veuillez saisir la commande>>>>
Vous pouvez voir le client1Et le client2 C'est une opération simultanée , Le serveur a reçu deux messages en même temps
Trois、 Voici une introduction basée sur UDPDesockertserver Des idées concurrentes
Code du serveur:
import socketserver
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
client_data=self.request[0]
server=self.request[1]
client_addr=self.client_address
print(' Données envoyées par le client %s'%client_data)
server.sendto(client_data.upper(),client_addr)
s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyRequestHandle)
s.serve_forever()
# C'est l'équivalent d'être responsable de la collecte du cycle seulement
'''
s.serve_forever()=>équivalent au code suivant
while True:
data,client_addr=server.accept()
Démarrer un thread pour faire le suivi (data,client_addr)
'''
Client1Code:
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# Protocole de datagramme=》udpAccord
while True:
msg=input('>>>>')
client.sendto(msg.encode('utf-8'),("127.0.0.1",8080))
data,server_addr=client.recvfrom(1024)
print(data.decode('utf-8'),server_addr)
client.close()
Client2Code:
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# Protocole de datagramme=》udpAccord
while True:
msg=input('>>>>')
client.sendto(msg.encode('utf-8'),("127.0.0.1",8080))
data,server_addr=client.recvfrom(1024)
print(data.decode('utf-8'),server_addr)
client.close()
Le résultat de l'opération est:
# Code du serveur:
Données envoyées par le client b'asa'
Données envoyées par le client b'asasa'
Données envoyées par le client b'asasasa'
# Client1Code:
>>>>asa
ASA ('127.0.0.1', 8080)
>>>>asasa
ASASA ('127.0.0.1', 8080)
>>>>
#Client2Code:
>>>>asasasa
ASASASA ('127.0.0.1', 8080)
>>>>
Quatre、AvecsockertserverBasé surTCP Implémenter des commandes d'exécution à distance multi - clients
Serveur:
import socketserver
import subprocess
import struct
import json
class MyRequestHandle(socketserver.BaseRequestHandler):
def handle(self):
print(self.request) # Si ouitcpAccord,self.request=>conn
# print(self.client_address)
while True:
try:
cmd = self.request.recv(1024)
if len(cmd) == 0:
break
obj = subprocess.Popen(cmd.decode('utf-8'), # pycharmLe format par défaut estutf-8
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout_res = obj.stdout.read()
stderr_res = obj.stderr.read()
total_size = len(stdout_res) + len(stderr_res)
header_dic = {
'total_size': total_size,
'client_address':self.client_address
}
print('Client:%s La longueur de la commande est :%d'%(header_dic['client_address'],header_dic['total_size']))
json_str = json.dumps(header_dic)
json_str_bytes = json_str.encode('utf-8')
# 2、 Longueur de la tête de départ
x = struct.pack('i', len(json_str_bytes)) # Convertir les formes enbytesType
self.request.send(x)
# 3、 Informations de départ
self.request.send(json_str_bytes)
# 4Rediffuser les données réelles
self.request.send(stdout_res + stderr_res)
except Exception:
break
self.request.close()
'''
s.serve_forever()=>équivalent au code suivant
while True:
conn,client_addr=server.accept()
Démarrer un thread(conn,client_addr)
'''
# Le serveur devrait faire deux choses
# 1、La première chose: Boucle pour extraire une demande de lien d'un pool de demi - liens et établir un lien bidirectionnel avec elle ,Obtenir l'objet lié
s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyRequestHandle)
s.serve_forever()
# 2、Obtenir l'objet lié,Cycle de communication avec==>handle
Client1
from socket import *
import struct
import json
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg=input('Veuillez saisir la commande>>>>').strip()
if len(msg)==0:
continue
client.send((msg.encode('utf-8')))
# Résoudre les problèmes de collage:
# Un.、Retirez d'abord la tête de longueur fixe:Analyser la description des données,Y compris la taille totale des donnéestotal_size
# 1、Reçu en premier4Octets, Extraire la longueur de la tête à fermer
x = client.recv(4)
header = struct.unpack('i', x)[0]
# 2、 Recevoir l'en - tête et analyser
json_str_bytes = client.recv(header)
json_str = json_str_bytes.decode('utf-8')
header_dic =json.loads(json_str)
total_size = header_dic['total_size']
# 3、 Recevoir des données réelles
recv_size=0
while recv_size<total_size:
recv_data=client.recv(1024)# Lorsque les données reçues dépassent1024Heure,Le reste des données restera dans le cache du client,Les nouvelles données seront également mises en cache par le client,Attendez que les données restantes soient reçues avant de recevoir de nouvelles données
recv_size+=len(recv_data)
print(recv_data.decode('gbk'),end='')# windowsPar défautgbkFormat,Le décodage doit êtregbkFormat
else:
print()
Client2
from socket import *
import struct
import json
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg=input('Veuillez saisir la commande>>>>').strip()
if len(msg)==0:
continue
client.send((msg.encode('utf-8')))
# Résoudre les problèmes de collage:
# Un.、Retirez d'abord la tête de longueur fixe:Analyser la description des données,Y compris la taille totale des donnéestotal_size
# 1、Reçu en premier4Octets, Extraire la longueur de la tête à fermer
x = client.recv(4)
header = struct.unpack('i', x)[0]
# 2、 Recevoir l'en - tête et analyser
json_str_bytes = client.recv(header)
json_str = json_str_bytes.decode('utf-8')
header_dic =json.loads(json_str)
total_size = header_dic['total_size']
# 3、 Recevoir des données réelles
recv_size=0
while recv_size<total_size:
recv_data=client.recv(1024)# Lorsque les données reçues dépassent1024Heure,Le reste des données restera dans le cache du client,Les nouvelles données seront également mises en cache par le client,Attendez que les données restantes soient reçues avant de recevoir de nouvelles données
recv_size+=len(recv_data)
print(recv_data.decode('gbk'),end='')# windowsPar défautgbkFormat,Le décodage doit êtregbkFormat
else:
print()
Résultats des opérations:
# Résultats du serveur :
<socket.socket fd=380, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64118)>
Client:('127.0.0.1', 64118) La longueur de la commande est :20828
<socket.socket fd=752, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64121)>
Client:('127.0.0.1', 64121) La longueur de la commande est :583
# Client1Résultats:
Veuillez saisir la commande>>>>tasklist
Nom de l'image PID Nom de la session Session# Utilisation de la mémoire
========================= ======== ================ =========== ============
System Idle Process 0 Services 0 8 K
System 4 Services 0 84 K
Registry 124 Services 0 63,832 K
smss.exe 520 Services 0 1,036 K
csrss.exe 736 Services 0 5,152 K
wininit.exe 824 Services 0 5,752 K
csrss.exe 836 Console 1 6,856 K
services.exe 904 Services 0 9,748 K
lsass.exe 924 Services 0 24,384 K
svchost.exe 528 Services 0 33,208 K
fontdrvhost.exe 576 Services 0 2,452 K
svchost.exe 936 Services 0 16,768 K
svchost.exe 1044 Services 0 10,024 K
winlogon.exe 1212 Console 1 12,444 K
fontdrvhost.exe 1276 Console 1 10,464 K
dwm.exe 1356 Console 1 92,164 K
svchost.exe 1416 Services 0 10,700 K
svchost.exe 1516 Services 0 9,760 K
svchost.exe 1528 Services
.......................
conhost.exe 3528 Console 1 11,800 K
cmd.exe 8540 Console 1 5,092 K
tasklist.exe 15936 Console 1 9,652 K
Veuillez saisir la commande>>>>
# Client2
Veuillez saisir la commande>>>>dir
Drive D Le volume dans est Tous les logiciels de fichiers jetés ici
Le numéro de série du volume est C0F9-5D0A
D:\Nouveau dossier\pythonProject1\shujialianxi\Basé sursocketserver Mise en œuvre simultanée des modèles \Basé surTCP Table des matières
2021/11/25 00:59 <DIR> .
2021/11/25 00:59 <DIR> ..
2021/11/25 00:01 <DIR> sockertserverUtilisation de base
2021/11/24 11:46 0 __init__.py
2021/11/24 11:44 328 Client.py
2021/11/24 11:44 328 Client2.py
2021/11/25 00:59 2,171 Serveur.py
4 Fichiers 2,827 Octets
3 Catalogues 37,787,205,632 Octets disponibles
Veuillez saisir la commande>>>>