2009-03-26 7 views
9

Diciamo che ho una connessione socket e il listener di terze parti dall'altra parte si aspetta di vedere i dati che scorrono in modo molto strutturato. Ad esempio, cerca un byte senza segno che denoti un tipo di messaggio inviato, seguito da un intero senza segno che denota la lunghezza del messaggio, quindi un altro byte senza segno che è in realtà un campo bit con alcuni flag impostati o non impostati ed ecc.Scrittura di dati binari su un socket (o file) con Python

Come farei questo in python? Mi sto solo chiedendo come generare in modo affidabile questi dati e assicurarmi che lo stia mandando correttamente (cioè che sto davvero inviando un byte senza segno piuttosto che dire un intero con segno o peggio, una stringa).

risposta

11

Utilizzare il modulo struct per creare un buffer e scriverlo.

0

Al livello più basso, I/O socket consiste nel leggere o scrivere una stringa di valori di byte in un socket. Per fare questo, codifico le informazioni da scrivere come una stringa di caratteri contenente i valori di byte e li scrivo sul socket. Lo faccio creando una superstringa e quindi aggiungendo un personaggio alla volta. per esempio, per creare un Modbus/Ethernet richiesta di lettura:

readRequest = """""" 
    readRequest += chr(self.transactionID/0x100) # Transaction ID MSB   (0) 
    readRequest += chr(self.transactionID % 0x100) # Transaction ID LSB   (1) 
    readRequest += chr(0)       # Protocol ID MSB (Always 0) (2) 
    readRequest += chr(0)       # Protocol ID LSB (Always 0) (3) 
    readRequest += chr(0)       # Length MSB (Always 0)  (4) 
    readRequest += chr(6)       # Length LSB (Always 6)  (5) 
    readRequest += chr(0)       # Unit ID (Always 0)   (6) 

    readRequest += chr(0x04)      # Function code 4  (0) 
    readRequest += chr(startOffset/0x100)   # Starting offset MSB (1) 
    readRequest += chr(startOffset % 0x100)   # Starting offset LSB (2) 
    readRequest += chr(0)       # Word count MSB  (3) 
    readRequest += chr(2 * nToRead)     # Word count LSB  (4) 

    sockOutfile.write(readRequest) 

per convertire i valori più byte in stringhe di caratteri in modo che possano essere aggiunti sulla stringa di I/O, utilizzare la funzione nel modulo struct 'Pack()' . Questa funzione converte uno o più valori di byte singoli o multipli in una stringa di valori di byte singoli.

Naturalmente, questo metodo è semplice quanto un martello. Dovrà essere corretto quando la codifica dei caratteri predefinita in una stringa è Unicode anziché ASCII.

+0

Questa non è una buona idea. È soggetto a errori e difficile da mantenere. Il modulo struct è un modo molto migliore per farlo. – Ferruccio

+0

Sì, devo essere d'accordo. Sfortunatamente, l'ho scritto durante l'apprendimento di Python e l'ho scritto come se scrivessi ancora in C. – mkClark

4

Un modo molto elegante per gestire le transizioni di tesi tra oggetti Python e una rappresentazione binaria (entrambe le direzioni) utilizza lo Construct library.

Nella loro documentazione troverete molti buoni esempi di utilizzo. L'ho usato da molti anni per i protocolli di comunicazione seriale e per la decodifica dei dati binari.