我正在制作一个简单的Python应用程序,它将允许人们通过CLI相互通信。我对套接字模块比较陌生,但是我的代码没有问题。除了一个。当我运行两个脚本(chatclient.py和chatserver.py)时,它们运行良好。服务器启动,客户端将询问用户其姓名和消息。但是,单击回车发送消息后,我收到:

TypeError: decoding str not supported

我试过使用.encode('utf-8)/.decode('utf-8'),但仍然是相同的错误。该代码将在下面(带有关于“错误”代码的多个注释)。
#client.py
import socket
import threading
import time

tLock = threading.Lock()    #creates a lock for the thread and prevents output to the screen
shutdown = False

def receiving(name, sock):
    while not shutdown: #while the program is still running
        try:
            tLock.acquire() #acquires the lock
            while True:
                data, addr = sock.recv(1024).decode('utf-8')    #gets the data and address from the data received
                print(str(data))
        except:
            pass

        finally:
            tLock.release() #releases the lock

host = "127.0.0.1"  #uses localhost as the host
port = 0 #picks up any free port on the computer

server = ("127.0.0.1",5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)

rt = threading.Thread(target=receiving, args=("RecvThread", s))
rt.start()

'''name = input("Enter your name: ")
message = input("> ")
while message != "q":
    if message != '':
        print("From ",name)
        s.sendto(str(name, message), (host,port)).decode('utf-8')'''

    tLock.acquire()
    message = input('')
    tLock.release()
    time.sleep(0.5)

shutdown = True
rt.join()
s.close()

^^^客户端
#server.py
import socket
import time

host = "127.0.0.1"   #makes localhost the host server
port = 5000          #uses any random port between 1024 and 65535

clients = []

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    #creates a new socket object
s.bind((host,port))   #binds the host and port to socket object
s.setblocking(0)      #sets the blocking to 0 (essentially no blocking)

quitting = False
print("The server has now started on ",time.ctime(time.time()))

while not quitting: #while quitting hasn't happened
    try:
        data, addr = s.recvfrom(1024).decode('utf-8') #tries to get data and address from the data coming in
        if "Quit" in data: #if the data has quit in it
            quitting = True #quitting = true meaning the while not quitting loop would break
        if addr not in clients: #if the address given is not in the list 'Clients'
            clients.append(addr)  #then it will append it to the list

        print(time.ctime(time.time()),"- ",str(addr).decode('utf-8')," : ",str(data).decode('utf-8'))   #prints the time, the address and the message

        for client in clients:  #for each client in the list of clients
            s.sendto(bytes(data, 'utf-8'))   #send the data to the clients
            s.sendto(bytes(client, 'utf-8'))

    except:
        pass

s.close()

^^^服务器

最佳答案

如果您将2个或多个值传递给str,它将尝试解码,但是在您的情况下,第一个参数已经是字符串对象(因为input函数的返回值是string);导致错误。

>>> str('a')
'a'
>>> str('a', 'utf-8')   # trying to decode (the 2nd arg. is encoding)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: decoding str is not supported
>>> str(b'a', 'utf-8')
'a'

除此之外,您需要将bytes对象传递给socket.sendto作为第一个参数。编码字符串以获取字节对象:
>>> 'a'.encode()  # You can omit encoding arg.; `utf-8` is default in Python 3.x
b'a'
>>> 'a'.encode('utf-8')
b'a'

替换下面的客户端代码行:
s.sendto(str(name, message), (host,port)).decode('utf-8')

和:
s.sendto('{}: {}'.format(name, message).encode('utf-8'), (host,port))
data, addr = s.recvfrom(1024).decode('utf-8')

上面的线也是错误的。 socket.recvfrom(..)返回(消息,地址)的元组。 tuple没有decode方法。您只需要解码message
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')

服务器
import socket
import time

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 5000))

print("The server has now started on ", time.ctime())

clients = []
while True:
    data, addr = s.recvfrom(1024)
    text = data.decode('utf-8')
    if "Quit" in text:
        break

    if addr not in clients:
        clients.append(addr)

    print(time.ctime(), "-", addr, ":", text)
    for client in clients:
        s.sendto(data, client)

s.close()

关于python - Python3套接字模块: decoding str,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42467634/

10-13 02:29