2015-10-07 14 views
27

Poniżej znajduje się kod, który próbuje zmodyfikować wejście dostarczonego przez użytkownika za pomocą gniazd:TypeError: Wymagana jest obiektem bajtów podobny, nie „str”

from socket import * 

serverName = '127.0.0.1' 
serverPort = 12000 
clientSocket = socket(AF_INET, SOCK_DGRAM) 
message = input('Input lowercase sentence:') 
clientSocket.sendto(message,(serverName, serverPort)) 
modifiedMessage, serverAddress = clientSocket.recvfrom(2048) 
print (modifiedMessage) 
clientSocket.close() 

Kiedy go wykonać i dostarczyć dane wejściowe występuje następujący błąd:

Co mogę zrobić, aby rozwiązać ten problem?

+4

Pierwszy argument ("komunikat") musi być bajtami, ale podajesz ciąg znaków. Powinieneś go zakodować przed wysłaniem, np. 'wiadomość.zakodować ('utf-8') ' – mgilson

+0

ale jest to trzeba przekazać ciąg do serwera nie bajt – sri

+0

z gniazda import * serverName = 'hostname' ServerPort = 12000 clientSocket = socket (AF_INET, SOCK_DGRAM) wiadomości = input ("Wpisz małe zdanie:") message.encode ('utf-8') clientSocket.sendto (wiadomość, (nazwa_serwera, serverPort)) modifiedMessage, serverAddress = clientSocket.recvfrom (2048) print (modifiedMessage) clientSocket.close() – sri

Odpowiedz

45

Ten kod jest prawdopodobnie dobry dla Pythona 2. Ale w Pythonie 3 spowoduje to problem, coś związanego z kodowaniem bitowym. Próbowałem zrobić prosty serwer TCP i napotkałem ten sam problem. Kodowanie działało dla mnie. Wypróbuj to za pomocą polecenia sendto.

clientSocket.sendto(message.encode(),(serverName, serverPort)) 

Podobnie należałoby użyć .decode() do odbioru danych po stronie serwera UDP, jeśli chcesz go wydrukować dokładnie tak, jak została wysłana.

+0

kodowanie i dekodowanie po obu stronach zwiększenia opóźnienia połączenia? Gdyby tak było, python2 faktycznie byłby szybszy w wysyłaniu danych niż python3 – Max

+0

Moim zdaniem, nie wpłynie to na wydajność, taką jak opóźnienie itd. Jednak nie próbowałem eksperymentować z nią samodzielnie, więc nie jestem tego pewien. – Umair47

6

Trochę kodowania może rozwiązać ten problem:

Client Side:

message = input("->") 
clientSocket.sendto(message.encode('utf-8'), (address, port)) 

Server Side:

data = s.recv(1024) 
modifiedMessage, serverAddress = clientSocket.recvfrom(message.decode('utf-8')) 
+1

Twój klient nie będzie działał: sendto wymaga 3 parametrów, wiadomość adres serwera i powiązany port – dlewin

+0

@dlewin Masz rację, dobry połów. Zaktualizowałem to – Wlliam

3

Wystarczy wymienić parametr wiadomość przekazywana w clientSocket.sendto(message,(serverName, serverPort)) do clientSocket.sendto(message.encode(),(serverName, serverPort)). Wtedy można z powodzeniem uruchomić w w python3

0

Gdy wystąpi błąd z tym komunikatem użytku my_string.encode().

(gdzie my_string jest ciągiem znaków przekazywanym do funkcji/metody).

encode metoda str obiektów zwraca zakodowaną wersję napisu jako bytes object które można następnie wykorzystać. W tym konkretnym przypadku metody gniazd such as .sendoczekują obiektu bajtów jako danych do wysłania, nie jako obiektu tekstowego.

Skoro masz obiekt typu str i jesteś przekazaniem go do funkcji/metody, która spodziewa obiekt typu bytes, błąd jest podniesiona, które jasno wyjaśnia, że:

TypeError: a bytes-like object is required, not 'str' 

Więc encode potrzebna jest metoda łańcuchów, stosowane na wartości str i przekazujących bytes wartość:

>>> s = "Hello world" 
>>> print(type(s)) 
<class 'str'> 
>>> byte_s = s.encode() 
>>> print(type(byte_s)) 
<class 'bytes'> 
>>> print(byte_s) 
b"Hello world" 

Tutaj prefiksu b w b'Hello world' oznacza, że ​​jest to rzeczywiście obiekt typu bajty. Następnie można go przekazać do dowolnej funkcji, która oczekuje, aby działał bez zakłóceń.

Powiązane problemy