Python3 Socket TypeError: a bytes-like object is required, not 'str' error prompt, python3typeerror
At present, I am studying basic python syntax and computer network courses. So I just learned python network programming in combination. I checked the third edition of "python core programming" and found that the sample code 2-1 returned an error ..... Long tangle
It is found that python3.5 and Python2.7 differ in the return value Decoding of sockets.
First, we will introduce the functions encode () and decode () for conversion between python bytes and str ()
- Str can be encoded as the specified bytes through the encode () method.
- If we read byte streams from the network or disk, the data we read is bytes. To change bytes to str, you need to use the decode () method:
2-1 example in python core programming book
TCP Server:
# Coding = UTF-8 # create a TCP server from socket import * from time import ctimeHOST = ''PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpSerSock = socket (AF_INET, SOCK_STREAM) # create a server socket tcpSerSock. bind (ADDR) # bind the socket to the address tcpSerSock. listen (5) # listen for connections, the maximum number of incoming connection requests while True: print ('Waiting for connection... ') tcpCliSock, addr = tcpSerSock. accept () print ('... connected from: ', addr) while True: data = tcpCliSock. recv (BUFSIZ) # print ('date = ', data) if not data: break tcpCliSock. send ('[% s] % s' % (ctime (), data) tcpCliSock. close () tcpSerSock. close ()
TCP client
#coding=utf-8from socket import *HOST = 'localhost' # or 'localhost'PORT = 21567BUFSIZ = 1024ADDR=(HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)while True: data = input('> ') print('data=',data); if not data: break tcpCliSock.send(data) data = tcpCliSock.recv(BUFSIZ) if not data: break print(data)tcpCliSock.close()
Returned error message:
TypeError: a bytes-like object is required, not 'str'
18 rowstcpCliSock.send(data)
The input parameter should be of the bytes type, rather than the str type.
So I went to Baidu and found that people found the same problem on StackOverflow, and a Scharron person gave me the answer:
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 stringthat you need to use as a byte string, you need toencode () 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 B "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 ()
So I checked the help manual of python3.5.
Socket. send (bytes [, flags])
Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. For further information on this topic, consult the Socket Programming HOWTO.Changed in version 3.5: If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising an InterruptedError exception (see PEP 475 for the rationale).
Socket. recv (bufsize [, flags])
Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.NoteFor best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096.Changed in version 3.5: If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising an InterruptedError exception (see PEP 475 for the rationale).
After correction:
Tcp Server
# Coding = UTF-8 # create a TCP server from socket import * from time import ctimeHOST = ''PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpSerSock = socket (AF_INET, SOCK_STREAM) # create a server socket tcpSerSock. bind (ADDR) # bind the socket to the address tcpSerSock. listen (5) # listen for connections, the maximum number of incoming connection requests 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 ()
Tcp client:
#coding=utf-8from socket import *HOST = 'localhost' # or 'localhost'PORT = 21567BUFSIZ = 1024ADDR=(HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)while True: data = input('> ') #print('data=',data); if not data: break tcpCliSock.send(data.encode()) data = tcpCliSock.recv(BUFSIZ).decode() if not data: break print(data)tcpCliSock.close()
Socket. sendto (bytes, address)
Socket. sendto (bytes, flags, address)
Send data to the socket. The socket should not be connected to a remote socket, since the destination socket is specified by address. The optional flags argument has the same meaning as for recv() above. Return the number of bytes sent. (The format of address depends on the address family — see above.)Changed in version 3.5: If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising an InterruptedError exception (see PEP 475 for the rationale).
Socket. recvfrom (bufsize [, flags])
Receive data from the socket. The return value is a pair (bytes, address) where bytes is a bytes object representing the data received and address is the address of the socket sending the data. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero. (The format of address depends on the address family — see above.)
Similarly, modify the udp Server:
from socket import *from time import ctimeHOST=''PORT=21546BUFSIZ=1024ADDR=(HOST,PORT)udpSerSock = socket(AF_INET,SOCK_DGRAM)udpSerSock.bind(ADDR)while True: print('waiting for message...') data,addr=udpSerSock.recvfrom(BUFSIZ) data=data.decode() udpSerSock.sendto(('[%s] %s'%(ctime(),data)).encode(),addr) print('...received from and returned to:',addr)udpSerSock.close()
Original: http://blog.csdn.net/yexiaohhjk/article/details/68066843