Python

2009-03-26 12 views
9

ile bir sokete (veya dosyaya) ikili veri yazma Bir soket bağlantım olduğunu ve diğer taraftaki 3. taraf dinleyicinin çok yapılandırılmış bir şekilde akan veriyi görmeyi beklediğini varsayalım. Örneğin, gönderilmekte olan bir iletinin türünü belirten bir imzasız bayt, ardından iletinin uzunluğunu ifade eden işaretsiz bir tamsayı, sonra da bazı bayrakların ayarlanmış ya da unset ile bir bit alanı olan bir başka imzalanmamış baytını arar.Python

Bunu pitonda nasıl yapardım? Sadece bu verileri nasıl güvenli bir şekilde üretebileceğimi ve doğru bir şekilde gönderdiğimi (örneğin, imzalı bir tamsayı veya daha kötüsü, bir dize yerine işaretsiz bir bayt gönderiyorum) emin olmak istiyorum.

cevap

11

Bir arabellek oluşturmak için struct modülünü kullanın ve bunu yazın.

0

En düşük seviyede, soket G/Ç bir sokete bir dizi bayt değeri okuma veya yazma işleminden oluşur. Bunu yapmak için, yazılacak bilgileri bayt değerlerini içeren bir karakter dizesi olarak kodlarım ve sokete yazdım. Bunu bir superstring oluşturarak ve bir kerede bir karakter ekleyerek yapıyorum. onlar G/Ç dize üzerine eklenebilir böylece 'Paketi()' yapı modülünde işlevini kullanın

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) 

karakter dizeleri içine baytlı değerlerini dönüştürmek için: örneğin, bir Modbus/Ethernet isteği okumak oluşturmak için . Bu işlev, bir veya daha fazla tek veya çok bayt değerini bir tek bayt değeri dizesine dönüştürür.

Elbette, bu yöntem çekiç kadar basittir. Bir dizede varsayılan karakter kodlaması ASCII yerine Unicode olduğunda düzeltilmesi gerekir.

+0

Bu iyi bir fikir değil. Bu hata eğilimli ve bakımı zor. Yapı modülü bunu yapmanın daha iyi bir yoludur. – Ferruccio

+0

Evet, kabul etmeliyim. Maalesef bunu Python'u öğrenirken yazdım ve sanki hala C yazıyormuşum gibi yazdım. – mkClark

4

Python nesneleri ile ikili gösterim (her iki yönde) arasındaki geçişleri işlemenin çok zarif bir yolu Construct library kullanıyor.

Belgelerinde, kullanmanın birçok güzel örneği bulacaksınız. Seri iletişim protokolleri ve ikili verileri çözmek için birkaç yıldır kendimi kullanıyordum.