2015-10-07 24 views
27

Sau đây là đoạn code mà cố gắng để sửa đổi các đầu vào được cung cấp bởi một người dùng bằng cách sử dụng ổ cắm:Lỗi Loại: một đối tượng byte giống như là bắt buộc, không phải là '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() 

Khi tôi thực hiện nó và cung cấp đầu vào lỗi sau xảy ra:

Input lowercase sentence:fdsgfdf 
Traceback (most recent call last): 
    File "C:\srinath files\NETWORKS\UDPclient.py", line 6, in <module> 
    clientSocket.sendto(message,(serverName, serverPort)) 
TypeError: a bytes-like object is required, not 'str' 

Tôi có thể làm gì để giải quyết vấn đề này?

+4

Đối số đầu tiên ('message') cần phải là byte, nhưng bạn đang chuyển một chuỗi. Bạn nên mã hóa nó trước khi gửi, ví dụ: 'tin nhắn.mã hóa ('utf-8') ' – mgilson

+0

nhưng vấn đề là tôi cần phải vượt qua chuỗi các máy chủ không bytes – sri

+0

từ ổ cắm nhập khẩu * serverName = 'hostname' serverPort = 12000 clientSocket = socket (AF_INET, SOCK_DGRAM) nhắn = đầu vào ('Chữ thường đầu vào:') message.encode ('utf-8') clientSocket.sendto (message, (tên máy chủ, serverPort)) modifiedMessage, serverAddress = clientSocket.recvfrom (2048) print (modifiedMessage) clientSocket.close() – sri

Trả lời

45

Mã này có thể là tốt cho Python 2. Nhưng trong Python 3, điều này sẽ gây ra một vấn đề, một cái gì đó liên quan đến mã hóa bit. Tôi đã cố gắng để làm cho một máy chủ TCP đơn giản và gặp phải cùng một vấn đề. Mã hóa đã làm việc cho tôi. Hãy thử điều này với lệnh sendto.

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

Tương tự bạn sẽ sử dụng .decode() để nhận dữ liệu ở phía máy chủ UDP, nếu bạn muốn in chính xác như được gửi.

+0

sẽ mã hóa và giải mã trên cả hai mặt của độ trễ tăng kết nối? Nếu như vậy python2 thực sự nhanh hơn trong việc gửi dữ liệu hơn python3 – Max

+0

Theo ý kiến ​​của tôi, điều này sẽ không ảnh hưởng đến hiệu suất như độ trễ, vv Tuy nhiên, tôi chưa thử nghiệm nó vì vậy tôi không thể chắc chắn về điều đó. – Umair47

6

Một chút mã hóa có thể giải quyết này:

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

Máy khách của bạn sẽ không hoạt động: sendto yêu cầu 3 tham số, thông báo địa chỉ máy chủ và cổng liên quan – dlewin

+0

@dlewin Bạn đúng, bắt tốt. Tôi đã cập nhật nó – Wlliam

3

Chỉ cần thay thế tham số thông điệp thông qua vào clientSocket.sendto(message,(serverName, serverPort))-clientSocket.sendto(message.encode(),(serverName, serverPort)). Sau đó, bạn sẽ thành công chạy trong trong python3

0

Bất cứ khi nào bạn gặp một lỗi với điều này nhắn sử dụng my_string.encode().

(trong đó my_string là chuỗi bạn chuyển đến hàm/phương pháp).

Phương pháp encode của str đối tượng trả về phiên bản mã hóa của chuỗi như một bytes object mà sau đó bạn có thể sử dụng. Trong trường hợp cụ thể này, các phương thức socket such as .sendmong đợi một đối tượng byte làm dữ liệu được gửi, không phải là đối tượng chuỗi.

Vì bạn có một đối tượng kiểu str và bạn đang đi qua nó để một hàm/phương pháp mà hy vọng một đối tượng kiểu bytes, một lỗi được nâng lên rõ ràng giải thích rằng:

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

Vì vậy, các encode phương pháp chuỗi là cần thiết, áp dụng trên giá trị str và trả về một giá trị bytes:

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

đây tiền tố b trong b'Hello world' biểu thị rằng đây thực sự là một đối tượng byte. Sau đó, bạn có thể truyền nó cho bất kỳ chức năng nào đang chờ nó để nó chạy trơn tru.

Các vấn đề liên quan