1. Programmation réseau Python
1.module de prise
Pour créer un socket, utilisez la fonction socket.socket(). Sa syntaxe est la suivante :
socket.socket (socket_family, socket_type, protocole = 0)
socket_family peut être les paramètres suivants :
socket.AF_INET IPv4 (par défaut)
socket.AF_INET6 IPv6
socket.AF_UNIX ne peut être utilisé que pour la communication inter-processus sur un seul système Unix
socket_type peut être les paramètres suivants :
socket.SOCK_STREAM socket de streaming, pour TCP (par défaut)
socket.SOCK_DGRAM socket de datagramme, pour UDP
socket.SOCK_RAW socket brut. Les sockets ordinaires ne peuvent pas traiter les messages réseau tels que ICMP et IGMP, mais SOCK_RAW le peut. Deuxièmement, SOCK_RAW peut également traiter les messages IPv4 spéciaux. De plus, en utilisant les sockets bruts, vous pouvez transmettre IP_HDRINCL Les options de socket sont construites par l'utilisateur dans l'en-tête IP.
socket.SOCK_RDM est une forme fiable d'UDP, c'est-à-dire que la livraison des datagrammes est garantie mais la commande n'est pas garantie. SOCK_RAM est utilisé pour fournir un accès de bas niveau au protocole d'origine et est utilisé lorsque certaines opérations spéciales doivent être effectuées, telles que l'envoi de messages ICMP. SOCK_RAM est généralement limité aux programmes exécutés par des utilisateurs expérimentés ou des administrateurs.
socket.SOCK_SEQPACKET Service de paquets continu et fiable
paramètres du protocole :
0 (par défaut) Le protocole associé à une famille d'adresses spécifique. S'il est 0, le système sélectionnera automatiquement un protocole approprié en fonction du format d'adresse et de la catégorie de socket.
2. Méthodes intégrées des objets socket
Fonctions de socket côté serveur
s.bind() lie l'adresse (adresse IP, port) au socket. Les paramètres doivent être au format tuple. Par exemple : s.bind(('127.0.0.1',8009))
s.listen(5) commence à écouter, 5 est le nombre maximum de connexions en attente
s.accept() accepte passivement les connexions client, bloque et attend les connexions.
Fonctions du socket client
s.connect() se connecte au serveur. Les paramètres doivent être au format tuple. Par exemple : s.connect(('127,0.0.1',8009))
Fonctions de prise à usage public
s.recv(1024) reçoit des données TCP, 1024 est la taille d'une réception de données
s.send(bytes) envoie des données TCP. Le format des données envoyées par python3 doit être au format octets.
s.sendall() envoie les données complètement et la boucle interne appelle send
s.close() ferme le socket
3.programme de démonstration
serveur
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import time
IP_PORT = ('127.0.0.1',8009)
BUF_SIZE = 1024
tcp_server = socket.socket()
tcp_server.bind(IP_PORT)
tcp_server.listen(5)
while True:
print("waiting for connection...")
conn,addr = tcp_server.accept()
print("...connected from:",addr)
while True:
data = tcp_server.recv(BUF_SIZE)
if not data:break
tcp_server.send('[%s] %s'%(time.ctime(),data))
tcp_server.close()
client
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
HOST = '127.0.0.1'
PORT = 8009
BUF_SIZE = 1024
ADDR = (HOST,PORT)
client = socket.socket()
client.connect(ADDR)
while True:
data = input(">>> ")
if not data:break
client.send(bytes(data,encoding='utf-8'))
recv_data = client.recv(BUF_SIZE)
if not recv_data:break
print(recv_data.decode())
client.close()
4. Démo simple du protocole personnalisé
Utiliser un protocole personnalisé pour transmettre des données de Python à Netty - Zhihu
Veuillez vous référer à l'utilisation de la bibliothèque struct couramment utilisée dans la programmation réseau.
python (29) : notes de développement struct module_python blog-CSDN blog_python struct module
Documentation de référence
socket — Interface réseau de bas niveau — Documentation Python 3.10.5
Explication détaillée du module socket dans python-Muzhuang Network Blog
https://www.csdn.net/tags/MtTaMgwsMjc1NzAyLWJsb2cO0O0O.html
reniflage de réseau
https://www.csdn.net/tags/MtTaAg0sNjEzNDQwLWJsb2cO0O0O.html
reniflage de réseau python experience_moyu blog de l'apprenant-blog CSDN_reniflage de réseau python
copier le code de détection du réseau
import socket
import threading
import time
import logging
import struct
import ctypes
activeDegree = dict()
flag = 1
'''
IP层 协议字段:占8比特。指明IP层所封装的上层协议类型,如ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)
'''
def main():
global activeDegree
global glag
# 获取本机IP地址
HOST = socket.gethostbyname(socket.gethostname())
print("HOST: ", HOST)
# 创建原始套接字,适用于Windows平台
# 对于其他系统,要把socket.IPPROTO_IP替换为socket.IPPROTO_ICMP
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
# s.connect((''))
# 设置在捕获数据包中含有IP包头
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# 启用混杂模式,捕获所有数据包
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# 开始捕获数据包
while flag:
data, addr = s.recvfrom(65535)
mac_len = parse_mac(data)
ip_len, pro = parse_ip(data)
if pro == 6:
parse_tcp(data, ip_len)
elif pro == 1:
parse_icmp(data, ip_len)
# if len(data) - mac_len - ip_len >= 8:
elif pro == 17:
parse_udp(data, mac_len + ip_len)
# print('mac: ', mac)
# print('get addr', addr)
host = addr[0]
activeDegree[host] = activeDegree.get(host, 0) + 1
# if addr[0] != HOST:
# print(addr[0])
# 关闭混杂模式
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
s.close()
def parse_mac(raw_buffer):
# parse ethernet header
eth_length = 14
eth_header = raw_buffer[:eth_length]
eth = struct.unpack('!6s6sH', eth_header)
eth_protocol = socket.ntohs(eth[2])
print('Destination MAC : ' + eth_addr(raw_buffer[0:6]) + \
' Source MAC : ' + eth_addr(raw_buffer[6:12]) + ' Protocol : ' + str(eth_protocol))
# print('P->13/14: '+eth_protocol(raw_buffer[12:14]))
return eth_length
def eth_addr(a):
b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (a[0], a[1], a[2], a[3], a[4], a[5])
return b
def parse_tcp(raw_buffer, iph_length):
tcp_header = raw_buffer[iph_length: iph_length + 20]
tcph = struct.unpack('!HHLLBBHHH', tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
print(('TCP => Source Port: {source_port}, Dest Port: {dest_port}'
' Sequence Number: {sequence} Acknowledgement: {acknowledgement}'
' TCP header length: {tcph_length}').format(
source_port=source_port, dest_port=dest_port,
sequence=sequence, acknowledgement=acknowledgement,
tcph_length=tcph_length
))
def parse_udp(raw_buffer, idx):
udph_length = 8
udp_header = raw_buffer[idx: idx + udph_length]
udph = struct.unpack('!HHHH', udp_header)
source_port = udph[0]
dest_port = udph[1]
length = udph[2]
checksum = udph[3]
print(('UDP => Source Port: {source_port}, Dest Port: {dest_port} '
'Length: {length} CheckSum: {checksum}').format(
source_port=source_port, dest_port=dest_port,
length=length, checksum=checksum
))
def parse_ip(raw_buffer):
# IP 头
ip_header = raw_buffer[0:20]
# 解析IP头
# see http://blog.guozengxin.cn/2013/07/25/python-struct-pack-unpack
iph = struct.unpack('!BBHHHBBH4s4s', ip_header)
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8])
d_addr = socket.inet_ntoa(iph[9])
print(('IP -> Version: {version}, Header Length: {header},'
'TTL: {ttl}, Protocol: {protocol}, Source IP: {source},'
'Destination IP: {destination}').format(
version=version, header=iph_length,
ttl=ttl, protocol=protocol, source=s_addr,
destination=d_addr
))
return iph_length, protocol
def parse_icmp(raw_buffer, iph_length):
buf = raw_buffer[iph_length : iph_length + ctypes.sizeof(ICMP)]
icmp_header = ICMP(buf)
print(('ICMP -> Type:%d, Code: %d, CheckSum: %d'
% (icmp_header.type, icmp_header.code, icmp_header.checksum)))
class ICMP(ctypes.Structure):
"""ICMP 结构体"""
_fields_ = [
('type', ctypes.c_ubyte),
('code', ctypes.c_ubyte),
('checksum', ctypes.c_ushort),
('unused', ctypes.c_ushort),
('next_hop_mtu', ctypes.c_ushort)
]
def __new__(self, socket_buffer):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer):
pass
t = threading.Thread(target=main)
t.start()
time.sleep(60)
flag = 0
t.join()
for item in activeDegree.items():
print(item)
strcut, phénomène de sac collant
Phénomène de paquets collants dans la programmation réseau - Zhihu
Une brève analyse du module struct en Python - poisson salé mélangé avec du sucre - Blog Garden