Python Socket TypeError: a bytes-like object is required, not 'str' 错误提示

在学习socket编程时,遇到代码返回如下错误: TypeError: a bytes-like object is required, not 'str' 
发现这里python3.5和Python2.7在套接字返回值解码上有区别。 

首先可以明确,在python3中默认的编码方式是unicode。unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节),因此 utf-16就是现在最常用的unicode版本。 不过考虑到utf8省空间,在文件里存的还是utf-8。

书中示例

服务端

 1 #coding=utf-8
 2 #创建TCP服务器
 3 from socket import *
 4 from time import ctime
 5 
 6 HOST=''
 7 PORT=21567
 8 BUFSIZ=1024
 9 ADDR=(HOST,PORT)
10 
11 tcpSerSock=socket(AF_INET,SOCK_STREAM) #创服务器套接字
12 tcpSerSock.bind(ADDR) #套接字与地址绑定
13 tcpSerSock.listen(5)  #监听连接,传入连接请求的最大数
14 
15 while True:
16     print('waiting for connection...')
17     tcpCliSock,addr =tcpSerSock.accept()
18     print('...connected from:',addr)
19 
20     while True:
21         data =tcpCliSock.recv(BUFSIZ)
22         #print('date=',data)
23         if not data:
24             break
25         tcpCliSock.send(('[%s] %s' %(ctime(),data)))
26 
27     tcpCliSock.close()
28 tcpSerSock.close()

客户端

 1 #coding=utf-8
 2 
 3 from socket import *
 4 
 5 HOST = 'localhost' #  or 'localhost'
 6 PORT = 21567
 7 BUFSIZ = 1024
 8 ADDR=(HOST,PORT)
 9 
10 tcpCliSock = socket(AF_INET,SOCK_STREAM)
11 tcpCliSock.connect(ADDR)
12 
13 while True:
14     data = input('> ')
15     print('data=',data);
16     if not data:
17         break
18     tcpCliSock.send(data)
19     data = tcpCliSock.recv(BUFSIZ)
20     if not data:
21         break
22     print(data)
23 
24 tcpCliSock.close() 

返回的错误提示: 
TypeError: a bytes-like object is required, not ‘str’ 

输入信息时,在客户端输入的是字符串(str类型),而代码中需要的是bytes类型,带着疑问去查原因,最终在StackOverflow上发现有人也出现同样的问题,且一个叫Scharron的人给出了解答:  

    In python 3, bytes strings and unicodestrings are now two different types. Since sockets are not aware of string encodings, they are using raw bytes strings, that have a slightly differentinterface from unicode strings.

So, now, whenever you have a unicode string that you need to use as a byte string, you need to encode() it. And whenyou have a byte string, you need to decode it to use it as a regular(python 2.x) string.

Unicode strings are quotes enclosedstrings. Bytes strings are being enclosed strings.

When you use client_socket.send(data),replace it by client_socket.send(data.encode()). When you get datausing data = client_socket.recv(512), replace it by data =client_socket.recv(512).decode()

因此,客户端传输信息时需要解码把  str类型  转换 bytes类型 用于传输,在接收到服务端信息后,需要进行编码,再把 bytes类型 转换成 str类型

以下为修改后的代码:

服务端

 1 #coding=utf-8
 2 #创建TCP服务器
 3 from socket import *
 4 from time import ctime
 5 
 6 HOST=''
 7 PORT=21567
 8 BUFSIZ=1024
 9 ADDR=(HOST,PORT)
10 
11 tcpSerSock=socket(AF_INET,SOCK_STREAM) #创服务器套接字
12 tcpSerSock.bind(ADDR) #套接字与地址绑定
13 tcpSerSock.listen(5)  #监听连接,传入连接请求的最大数
14 
15 while True:
16     print('waiting for connection...')
17     tcpCliSock,addr =tcpSerSock.accept()
18     print('...connected from:',addr)
19 
20     while True:
21         data =tcpCliSock.recv(BUFSIZ).decode()
22         print('date=',data)
23         if not data:
24             break
25         tcpCliSock.send(('[%s] %s' %(ctime(),data)).encode())
26 
27     tcpCliSock.close()
28 tcpSerSock.close()

客户端

#coding=utf-8
#创建TCP服务器
from socket import *
from time import ctime

HOST=''
PORT=21567
BUFSIZ=1024
ADDR=(HOST,PORT)

tcpSerSock=socket(AF_INET,SOCK_STREAM) #创服务器套接字
tcpSerSock.bind(ADDR) #套接字与地址绑定
tcpSerSock.listen(5)  #监听连接,传入连接请求的最大数

while True:
    print('waiting for connection...')
    tcpCliSock,addr =tcpSerSock.accept()
    print('...connected from:',addr)

    while True:
        data =tcpCliSock.recv(BUFSIZ).decode()
        print('date=',data)
        if not data:
            break
        tcpCliSock.send(('[%s] %s' %(ctime(),data)).encode())

    tcpCliSock.close()
tcpSerSock.close()

欢迎各位指正问题

posted @ 2019-06-29 09:17  变向过人  阅读(1321)  评论(0编辑  收藏  举报