2017-02-02 4 views
2

コードをPython 2.7からPython 3に変換しようとしていますが、何かが変更されたようです。私はソケット上でバイナリデータを受け取ろうとしていますが、今は動作しません。ここに私のコードです。TypeError:ソケットで作業中に暗黙的に 'bytes'オブジェクトをstrに変換できません

EDIT:送信コードを追加しました。また、私は実際に今のところうまくいかない、それは複雑すぎます。できる場合は、より良いデータの送受信方法があることが良いでしょう。あなたはバイトのデータを必要とするならば、

data = b'' 

を使用しなくて保つ文字列

data = data + newData.decode('utf-8') 

# or 

data = data + newData.decode('ascii') 

にデコードする必要がありますので

def recv(self): 
    # Receive the length of the incoming message (unpack the binary data) 
    dataLength = socket.ntohl(struct.unpack("I", self._recv(4))[0]) 

    # Receive the actual data 
    return self._recv(dataLength) 

def _recv(self, length): 
    try: 
     data = '' 
     recvLen = 0 
     while recvLen < length: 
      newData = self.sock.recv(length-recvLen) 

      if newData == '': 
       self.isConnected = False 
       raise exceptions.NetworkError(errors.CLOSE_CONNECTION, errno=errors.ERR_CLOSED_CONNECTION) 

      data = data + newData # TypeError here 
      recvLen += len(newData) 

     return data 
    except socket.error as se: 
     raise exceptions.NetworkError(str(se)) 

def send(self, data): 
    if type(data) is not str: 
     raise TypeError() 

    dataLength = len(data) 

    # Send the length of the message (int converted to network byte order and packed as binary data) 
    self._send(struct.pack("I", socket.htonl(dataLength)), 4) 

    # Send the actual data 
    self._send(data, dataLength) 

def _send(self, data, length): 
    sentLen = 0 
    while sentLen < length: 
     try: 
      amountSent = self.sock.send(data[sentLen:]) 
     except Exception: 
      self.isConnected = False 
      raise exceptions.NetworkError(errors.UNEXPECTED_CLOSE_CONNECTION) 

     if amountSent == 0: 
      self.isConnected = False 
      raise exceptions.NetworkError(errors.UNEXPECTED_CLOSE_CONNECTION) 

     sentLen += amountSent 
+0

常に置く** FULL **エラーメッセージ**。他にも有用な情報があります。どのラインが問題になるか。 – furas

+0

http://python3porting.com/problems.html#bytes-strings-and-unicode – Amber

+0

@furasを読んでみたいと思うかもしれません。質問にはコードを見れば必要なすべての情報が含まれています。エラーが発生します。エラーメッセージはタイトルにあります。あなたは他に何を探していますか? – ken596

答えて

4

のPython 3は、バイトとしてデータを送信.decode()

data = data + newData 

問題の新しいコードの編集:

送信すると、文字列をバイトに変換してからエンコードしてから長さを取得する必要があります。ネイティブ文字はユニコードとして長さ1を持ちますが、2バイト(またはそれ以上)を使用できます。

あなたが受け取ったら、バイトb''で作業し、最後に文字列にバイトを変換/デコードしてください。 **問題のコードで

コメントを見る# <--

def send(self, data): 
    if not isinstance(data, str): # <-- prefered method 
    #if type(data) is not str: 
     raise TypeError() 

    data = data.encode('utf-8') # <-- convert to bytes 

    # get size of bytes 
    dataLength = len(data) 

    # Send the length of the message (int converted to network byte order and packed as binary data) 
    self._send(struct.pack("I", socket.htonl(dataLength)), 4) 

    # Send the actual data 
    self._send(data, dataLength) 


def recv(self): 
    # Receive the length of the incoming message (unpack the binary data) 
    dataLength = socket.ntohl(struct.unpack("I", self._recv(4))[0]) 

    # Receive the actual data 
    return self._recv(dataLength).decode('utf-8') # <-- convert to string again 

def _recv(self, length): 
    try: 
     data = b'' # <-- use bytes 
     recvLen = 0 
     while recvLen < length: 
      newData = self.sock.recv(length-recvLen) 

      #if newData == b'': # <-- use bytes 
      if not newData: # <-- or 
       self.isConnected = False 
       raise exceptions.NetworkError(errors.CLOSE_CONNECTION, errno=errors.ERR_CLOSED_CONNECTION) 

      data = data + newData # TypeError here 
      recvLen += len(newData) 

     return data 
    except socket.error as se: 
     raise exceptions.NetworkError(str(se)) 
関連する問題