使用Python的简单'聊天'UDP客户端和服务器,不能使用`str`作为`send()`有效载荷

时间:2016-09-06 06:51:41

标签: python udp

我试图在python中使用UDP进行简单的“聊天”。我已经完成了客​​户端和服务器代码,

的客户端

import socket
fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM )
udp_ip = '127.0.0.1'
udp_port = 8014
while(True):
    message = input("Client :")
    fd.sendto(message, (udp_ip, udp_port))
    reply = fd.recvfrom(1000)
    print("Server:%s"%(reply))

服务器

import socket
udp_ip = '127.0.0.1'
udp_port = 8014
fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
fd.bind((udp_ip,udp_port))
while True:
    r = fd.recvfrom(1000)
    print("client : %s"%(r[0]))
    reply = input('server : ')
    client_address = r[1]
    fd.sendto(reply, client_address)  

在客户端,我得到了

python client.py 
Client :'haii'

在服务器端获取,

 python server.py 
 client : 'haii'
 server : 'hai there'
 Traceback (most recent call last):
 File "server.py", line 12, in <module>
 fd.sendto(reply, client_address)
 Type Error: a bytes-like object is required, not 'str'  

如何解决这个问题?那里有什么不对吗?

2 个答案:

答案 0 :(得分:2)

  

如何解决这个问题?那里有什么不对吗?

以及:

fd.sendto(reply, client_address)
Type Error: a bytes-like object is required, not 'str'

正如错误所说,你不能直接发送一个字符串(Python3字符串不仅仅是一个字节容器);您必须先将其转换为bytearray

 fd.sendto(bytearray(reply,"utf-8"), client_address)

请注意,您需要指定编码;这很有意义,如果你想一想在英语中不常用的字符在字节级别上有多么不同。这种转换的好处在于,您可以使用unicode发送几乎任何语言的文本:

fd.sendto(bytearray("सुंदर भाषा","utf-8"), client_address)

另一方面,你也会收到一个字节的东西,并且必须首先转换为字符串;再次,编码有所不同,您必须使用与发送相同的编码:

r = fd.recvfrom(1000)
received_msg = str(r, "utf-8")

您的print("%s" % r )使用默认编码隐式调用str,但这在网络事物中很可能不是一个好主意。使用utf -8几乎是将字符串编码为字节的非常好的方法。

给出最小量的背景:一个字符串应该真的像一个字符串 - 即一段由字母/字形/符号组成的文本,一个 text 的表示,而不是一些二进制内存。因此,当将一块内存发送给其他人时,您需要确保基于公共表示(在这种情况下为UTF8)理解您的文本。

答案 1 :(得分:0)

只需使用 fd.sendto(reply.encode(), client_address) 将字符串转换为字节。