Pourquoi mon message Protobuf est-il tronqué uniquement lorsqu’il est envoyé depuis une boîte Windows vers une boîte Linux?

J’utilise une combinaison de serveurs et de clients Python synchrones, simples et synchrones, pour envoyer des messages Google Protobuf via une connexion TCP. Le serveur s’exécute sous Windows XP en utilisant Python 2.5.4 et Google Protobuf 2.4.1. Le client s’exécute sur un serveur Ubuntu 12.04 utilisant Python 2.7.3 et Google Protobuf 2.4.1.

Lorsque j’exécute le serveur sur la machine XP et que j’essaie de lui parler à l’aide du client sur la machine Ubuntu, le serveur parsing correctement le message de demande et envoie le message de réponse google.protobuf.message.DecodeError: Truncated message , mais le client rencontre un google.protobuf.message.DecodeError: Truncated message erreur de google.protobuf.message.DecodeError: Truncated message .

Si je lance à la fois le client et le serveur sur la machine XP, je ne rencontre pas cette erreur et je ne rencontre pas cette erreur si je lance le serveur sur la machine Ubuntu et le client sur la machine XP.

Il semble que cela ait quelque chose à voir avec le message Protobuf proprement dit … Si j’utilise un message Protobuf très simple comme celui de l’exemple ci-dessous, les choses semblent bien fonctionner. Cependant, une fois que je commence à utiliser le message Protobuf que nous utilisons dans la production, je vois l’erreur. Il semble quand même étrange que je ne reçoive l’erreur que lorsque le serveur est sur Windows et que le client est sur Ubuntu.

Quelques idées sur ce qui pourrait se passer?! Compte tenu de certaines contraintes d’environnement, je dois respecter Python 2.5 sur la machine Windows et Google Protobuf 2.4.1.

exemple protobuf.proto

 message Foo { required ssortingng name = 1; } message Bar { required ssortingng name = 1; } message Sucka { required ssortingng name = 1; repeated Foo foos = 2; repeated Bar bars = 3; } message Result { enum Exception { NONE = 0; GENERIC = 1; } required Exception exception = 1; optional ssortingng message = 2; optional Sucka sucka = 3; } 

server.py

 import signal, socket, struct from protobuf import Sucka, Result class TestServer(): def __init__(self, host = '0.0.0.0', port = 9989): self.host = host self.port = port self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind((self.host, self.port)) self.socket.listen(1) self.running = False self.conn = None self.run() def run(self): def handle_exit(signum, stack): print 'Shutting down server in response to signal %s' % (str(signum)) self.running = False signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) print 'Waiting on a connection' self.running = True while self.running: try: self.conn, addr = self.socket.accept() print 'Connection from:', addr size_t = self.conn.recv(4) size = struct.unpack('!I', size_t) data = self.conn.recv(size[0]) if not data: raise Exception('No data... did the client close the connection?') result = Result() try: sucka = Sucka() sucka.ParseFromSsortingng(data) result.exception = result.NONE result.sucka.CopyFrom(sucka) except Exception, ex: print str(ex) result.exception = result.GENERIC result.message = 'Exception: %s' % (str(ex)) finally: if self.conn: self.conn.close() self.socket.close() if __name__ == '__main__': s = TestServer() 

client.py

 import socket, struct, time from protobuf import Sucka, Result class TestClient(): def __init__(self, sucka, host = '127.0.0.1', port = 9989): self.addr = (host, port) self.__call(sucka) def __call(self, sucka): size = sucka.ByteSize() size_t = struct.pack('!I', size) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(self.addr) sock.send(size_t) sock.send(sucka.SerializeToSsortingng()) size_t = sock.recv(4) size = struct.unpack('!I', size_t) data = sock.recv(size[0]) result = Result() result.ParseFromSsortingng(data) if result.exception != Result.NONE: raise Exception(result.message) print str(result.sucka) if __name__ == '__main__': import sys, os sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) from protobuf import Sucka sucka = Sucka() sucka.name = 'testing' for i in range(0, 25): foo = sucka.foos.add() foo.name = 'foo-%i-tester' % i for i in range(0, 25): bar = sucka.bars.add() bar.name = 'bar-%i-tester' % i c = TestClient(sucka, '127.0.0.1', 9989)