TCP客户端和服务器间传输数据遇到的TypeError: a bytes-like object is required, not 'str'问题
使用python实现python核心编程3第472页和474页的TCP时间戳服务器和客户端服务器间数据传输编程时遇到TypeError: a bytes-like object is required, not 'str'报错问题,经查找资料知道是Python中的字符串数据和字节数据在python3中不能混用所致,一博文 https://eli.thegreenplace.net/2012/01/30/the-bytesstr-dichotomy-in-python-3 对python3中字符串和字节数据间区别联系做了较详细解释。
下面是https://www.cnblogs.com/abclife/p/7445222.html 进行的译文
python 3中最重要的新特性可能就是将文本(text)和二进制数据做了更清晰的区分。文本总是用unicode进行编码,以str类型表示;而二进制数据以bytes类型表示。
在python3中,不能以任何隐式方式将str和bytes类型二者混合使用。不可以将str和bytes类型进行拼接,不能在str中搜索bytes数据(反之亦然),也不能将str作为参数传入需要bytes类型参数的函数(反之亦然)。
字符串和字节符之间划分界线是必然的。下面这个图解要牢记于心:

strings可以被编码(encode)成字bytes,bytes也可以解码(decode)成strings:
>>> '€20'.encode('utf-8')
b'\xe2\x82\xac20'
>>> b'\xe2\x82\xac20'.decode('utf-8')
'€20'
可以这样理解:
string是文本(text)的抽象表示。字符串(string)由字符组成,字符也是抽象的实体且与任何二进制表示无关。
当操纵字符串的时候,很多细节是不用了解的。我们可以分割、切片和拼接字符串,在字符串内部进行搜索。但并不在乎内部是如何表示的,也不用在意底层一个字符要花费多少byte。
只有在需要将string编码(encode)成byte的时候,比如:通过网络传输数据;或者需要将byte解码(decode)成string的时候,我们才会关注string和byte的区别。
传入encode和decode的参数是编码方式。编码是一种用二进制数据表示抽象字符的方式。目前有很多种编码。上面给出的UTF-8是其中一种,下面是另一种:
>>> '€20'.encode('iso-8859-15')
b'\xa420'
>>> b'\xa420'.decode('iso-8859-15')
'€20'
编码是这个转换过程中至关重要的一部分。若不编码,bytes对象b'\xa420'只是一堆比特位而已。编码赋予其含义。采用不同的编码,这堆比特位的含义就会大不同:
>>> b'\xa420'.decode('windows-1255')
'₪20'
因而服务器端编码
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) #开始TCP监听 while True:
print('waiting for connection...')
tcpSerSock,addr=tcpSerSock.accept()#被动接受TCP客户端连接,等待连接的到来
print('...connected from:',addr) while True:
data=tcpSerSock.recv(BUFSIZ)
print(data.decode()) #服务器接受到客户端发送来的数据是字节类型,需要转换为字符串类型
if not data:
break
tcpSerSock.send(('[%s] %s'%(ctime(),data)).encode()) # 网络传输数据前将字符串数据转化为字节类型
tcpSerSock.close()
tcpSerSock.close()
客户端编程
from socket import * HOST='localhost'
PORT=21567
BUFSIZ=1024
ADDR=(HOST,PORT) tcpCliSock=socket(AF_INET,SOCK_STREAM)
tcpCliSock.connect(ADDR) while True:
data=input('>')
if not data:
break
tcpCliSock.send(data.encode()) #网络传输数据前将字符串数据转化为字节类型
data=tcpCliSock.recv(BUFSIZ).decode() #将收到的字节类型数据转化为字符串数据
if not data:
break
print(data) tcpCliSock.close()
客户端显示
>what??
[Sat Mar 31 16:03:20 2018] b'what??'
>excuse me?
[Sat Mar 31 16:03:52 2018] b'excuse me?'
>
服务器端显示
waiting for connection...
...connected from: ('127.0.0.1', 50782)
what??
excuse me?
udp服务器端编程
from socket import *
from time import ctime HOST=''
PORT=21567
BUFSIZ=1024
ADDR=(HOST,PORT) udpSerSock=socket(AF_INET,SOCK_DGRAM)
udpSerSock.bind(ADDR) while True:
print('waiting for message...')
data,addr=udpSerSock.recvfrom(BUFSIZ) #data是字节对象,addr是字符串对象
print(data)
print(addr)
data=data.decode()
data='[%s]%s'%(ctime(),data)
udpSerSock.sendto(data.encode(),addr)
print('..received from and returned to:',addr) udpSerSock.close()
客户端编程
from socket import * HOST='localhost'
PORT=21567
BUFSIZ=1024
ADDR=(HOST,PORT) udpCliSock=socket(AF_INET,SOCK_DGRAM)
while True:
data=input('>').encode()
if not data:
break
udpCliSock.sendto(data,ADDR)
data,ADDR=udpCliSock.recvfrom(BUFSIZ)
if not data:
break
else:
print(data.decode())
# print(udpCliSock.close()) udpCliSock.close()
服务器端显示
waiting for message...
b'who is that?'
('127.0.0.1', 60959)
..received from and returned to: ('127.0.0.1', 60959)
waiting for message...
b'I am Jack'
('127.0.0.1', 60959)
..received from and returned to: ('127.0.0.1', 60959)
waiting for message...
b'sending through UDP'
('127.0.0.1', 60959)
..received from and returned to: ('127.0.0.1', 60959)
waiting for message...
客户端显示
>who is that?
[Sat Mar 31 16:47:15 2018]who is that?
>I am Jack
[Sat Mar 31 16:47:24 2018]I am Jack
>sending through UDP
[Sat Mar 31 16:47:32 2018]sending through UDP
>
TCP客户端和服务器间传输数据遇到的TypeError: a bytes-like object is required, not 'str'问题的更多相关文章
- 利用Python中SocketServer 实现客户端与服务器间非阻塞通信
利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信 版权声明 本文转自:http://blog.csdn.net/cnmilan/article/details/9664823 ...
- 【python】网络编程-SocketServer 实现客户端与服务器间非阻塞通信
利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信.首先,先了解下SocketServer模块中可供使用的类:BaseServer:包含服务器的核心功能与混合(mix-in)类 ...
- [JAVA] Tcp客户端和服务器简单代码
服务器: import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; im ...
- Java实验四 TCP客户端和服务器的应用
实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全 4.对通信内容进行摘要计算并验证 实验步骤 1.信息安全传送: 发送方A——————>接收方B A加密时,用B ...
- socket编程:客户端与服务器间的连接以及各函数的用法
在认真的看UNP之前,一直被socket编程说的云里雾里,今天我要让大家从整天上认识socket编程,让我们知道socket编程的整个流程和各个函数的用法.这样:我们在写一些简单的socket编程时就 ...
- Socket TCP客户端和服务器的实现
import java.io.*; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.S ...
- TCP客户端与服务器的实现
为了更容易理解,我们举一个小例子来说明服务器与客户端之间的连接过程. 有一个饭店,饭店里有服务员,服务员用于招待客人 特别要注意的是:要记住相关函数的各个参数都是什么,什么时候返回SOCKET_ERR ...
- tcp客户端从服务器下载文本文件
代码讲解: server import socket def send_file_client(new_client_socket, new_client_addr): # 接收客户端需要下载的文件名 ...
- 基于Qt的tcp客户端和服务器实现摄像头帧数据处理(客户端部分)
项目简述 实现客户端调用摄像头,并以帧的形式将每一帧传输到服务端,服务端将图片进行某些处理后再返回给客户端.(客户端与服务端通信代码部分参考<Qt5 开发及实例>) 项目步骤 客户端的编写 ...
随机推荐
- 配置LANMP环境(3)-- 安装anmp前准备与实用软件安装
一.安装配置vim 1.安装 yum -y install vim* 2.创建文件夹 mkdir -p /etc/vim/ 3.配置 vim ~/.vimrc "插入模式时 光标的上下左右 ...
- js获取屏幕的大小等信息
<html><script>function a(){document.write("屏幕分辨率为:"+screen.width+"*" ...
- jvm(13)-线程安全与锁优化
[0]README 0.1)本文部分文字转自“深入理解jvm”, 旨在学习 线程安全与锁优化 的基础知识: 0.2)本文知识对于理解 java并发编程非常有用,个人觉得,所以我总结的很详细: [1]概 ...
- dm8148 开发之---4路解码器tvp5158
通过采用自动对比度控制与视频噪声过滤技术的全新 TVP515x 器件,采集4通道视频,可带来优异图像质量并实现市场领先的视频解码性能德州仪器 (TI) 宣布推出可实现优异图像质量的新型 TVP5158 ...
- diamond源码阅读-循环探测配置信息是否变化rotateCheckConfigInfo
rotateCheckConfigInfo 这是一个定时任务,循环调用 /** * 循环探测配置信息是否变化,如果变化,则再次向DiamondServer请求获取对应的配置信息 */ private ...
- ChemDraw是这样预测诺氟沙星NMR谱
化学绘图软件ChemDraw是一款在生化领域都可以使用的软件,诺氟沙星是一款常用的肠炎药,是生物化学领域的常见研究对象,在研究过程中需要预测它的NMR谱.这个时候如果用最新的ChemOffice 15 ...
- mysql的体系架构和存储引擎
定义数据库和实例 数据库:物理操作系统的文件或其他形式文件类型的集合.在mysql数据库中,数据库文件可以是frm.MYD.MYI.ibd结尾的文件. 实例:MySQL数据库由后台线程以及一个共享内存 ...
- Eclipse 启动时闪退问题解决方案
一.以前Eclipse都可以正常使用,突然有一天不能启动了,点击图标后启动画面一闪之后就消失了,以下是一些解决方案: 1. 找到Eclipse目录下的eclipse.exe,右键点击->发送到桌 ...
- ubuntu环境初始化
0. 在Ubuntu系统中永久修改主机名也比较简单.主机名存放在/etc/hostname文件中,修改主机名时,编辑hostname文件,在文件中输入新的主机名并保存该文件即可 1.打开termini ...
- Hints of sd0061(快排思想)
Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...