2017-08-29 3 views
1

Je dois envoyer des tableaux numpy entre les programmes Python2 et Python3 qui s'exécutent simultanément. Après avoir fait quelques recherches, j'ai décidé d'envoyer des cornichons sur une connexion socket.Envoi de tableaux numpy sur socket entre les versions Python, erreur ASCII

Je suis capable d'établir une connexion et d'envoyer des chaînes de va-et-vient, mais essayer d'envoyer des tableaux numpy entraîne une erreur ASCII. Voici ce que mon client/serveur font:

### Imports on both client and server ### 
import socket as sc 
import numpy 
try: 
    import cPickle as pickle 
except ImportError: 
    import pickle 
pickle.HIGHEST_PROTOCOL = 2 

### Python2 client ### 
data= numpy.ones((1, 60)) 
sock.connect(SERVER_ADDR) 

try: 
    serialized_data = pickle.dumps(data, protocol=2) 
except pickle.PicklingError as e: 
    raise e 

try: 
    sock.send(serialized_data) 
except sc.error as e: 
    logging.error('Connection ended') 

### Python3 server ### 
""" 
Given a client socket, and until the client has closed the session: 
- receive input from client 
- unpickle and print it 
""" 

while client != '': 
    try: 
     data = client.recv(4096) 
    except sc.error as e: 
     if e.errno != errno.ECONNRESET: 
      print('Connection ended') 
    else: 
     try: 
      unserialized_input = pickle.loads(input) ##### ERROR HERE ##### 
     except pickle.UnpicklingError as e: 
      raise e 
     else: 
      print(unserialized_input) 

### Error on server ### 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 6: ordinal not in range(128) 

Je recherche à essayer pour les questions liées, mais n'a pas pu trouver quoi que ce soit pertinent, sauf la solution proposée here, qui ne fonctionne pas pour moi puisque je dois utiliser python2 . Je ne suis pas sûr de savoir comment continuer. Des idées?

+0

Avez-vous regardé https://docs.python.org/3/library/pickle. html # pickle.loads? – pypypy

+0

TCP est un protocole de diffusion. Comment savez-vous que vous avez reçu un message complet? Vous devez mettre en œuvre un protocole pour vous assurer que vous avez reçu les données complètes. –

Répondre

1

J'ai reproduit votre erreur en exécutant le serveur sur Python 3 et le client sur Python 2. Le code suivant est un exemple qui peut exécuter le serveur et le client sur n'importe quelle combinaison de Python. pickle.loads sur Python 3 par défaut pour décoder des chaînes avec ascii. Pour les laisser comme octets d'origine envoyés, ajoutez encoding='bytes' en tant que paramètre. Mon protocole est de "lire tout depuis le client jusqu'à ce que le client ferme la connexion, puis la désérialise". Si vous souhaitez conserver la connexion ouverte et envoyer plus d'un blob sérialisé, vous devez définir un protocole indiquant la longueur du blob sérialisé.

client:

import socket 
import numpy 

try: 
    import cPickle as pickle 
except ImportError: 
    import pickle 

sock = socket.socket() 
data= numpy.ones((1, 60)) 
sock.connect(('localhost',8000)) 
serialized_data = pickle.dumps(data, protocol=2) 
sock.sendall(serialized_data) 
sock.close() 
sock = socket.socket() 
data= numpy.zeros((1, 60)) 
sock.connect(('localhost',8000)) 
serialized_data = pickle.dumps(data, protocol=2) 
sock.sendall(serialized_data) 
sock.close() 
serveur

:

from __future__ import print_function 
import sys 
import socket 
import numpy 

try: 
    import cPickle as pickle 
except ImportError: 
    import pickle 

s = socket.socket() 
s.bind((b'',8000)) 
s.listen(1) 
while True: 
    c,a = s.accept() 
    data = b'' 
    while True: 
     block = c.recv(4096) 
     if not block: break 
     data += block 
    c.close() 
    if sys.version_info.major < 3: 
     unserialized_input = pickle.loads(data) 
    else: 
     unserialized_input = pickle.loads(data,encoding='bytes') 
    print(unserialized_input) 

Sortie:

[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 
    1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 
    1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 
    1. 1. 1. 1. 1. 1.]] 
[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 
    0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 
    0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 
    0. 0. 0. 0. 0. 0.]]