Python3.X Socket 一个编码与解码的坑

简介:

在看《Python核心编程》第三版 讲述网络编程Socket的知识,在练习中采用Python 3 的代码中遇到一个与编码解码有关的坑,本文将给予详细的介绍。

软件环境

Python: 3.6.0
库: socket

1. 问题初见

仿照书中的代码(中文版 55-56页) 加上自己的一点改动在我的环境中不能运行,总是报这个错误:TypeError: a bytes-like object is required, not 'str'

这里是我的客户端Socket代码

from socket import *
from time import ctime

HOST = 'localhost'
PORT = 10001
ADDRESS = (HOST, PORT)

clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect(ADDRESS)

while True:
    data = input('请输入消息:')
    if not data:
        break

    clientSocket.send(data)
    data = clientSocket.recv(1024)
    if not data:
        break

    print("服务器返回的消息是:", data.decode('utf-8'))

clientSocket.close()

我的环境是: Python 3.6.0, 怎么破?

2. 研究错误 TypeError: a bytes-like object is required, not 'str'

错误的位置是在代码clientSocket.send(data)部分,但是翻看python socket .send()源代码_socket.py 方法说明

def send(self, data, flags=None): # real signature unknown; restored from __doc__

    send(data[, flags]) -> count

    Send a data string to the socket.  For the optional flags
    argument, see the Unix manual.  Return the number of bytes
    sent; this may be less than len(data) if the network is busy.

    pass

这个send方法的参数期望的是一个 "a data string" 啊,而我确实给了一个string。

哪里出问题了? 继续查看官方文档Socket,发现原因了。

官方对Socket的说明:

socket.send(bytes[, flags])

可以看到在Python 3中send()方法期望的是一个bytes, 而不是str
看来我我前面看到的是假的源代码参数的说明。哈哈。

3. 用encode() 方法解决客户端Socket 发送错误

解决错误的方法就是在调用send()方法之前对字符串类型数据进行encode,将字符串转化成bytes
代码如下:

clientSocket.send(data.encode())

与此同时,在服务端运行的时候也遇到了类似数据无法接收的问题。
如下代码得到的data,是无法直接打印的。
data = clientSocket.recv(1024)

如果要打印data数据的话,也要调用decode()从而将数据从bytes转化为str。

4. encode() 和 decode()

encode()编码 : str -> bytes
decode()解码 : bytes -> str

默认的encoding是 utf-8

更多内容见官方文档:
str.encode()
bytes.decode()

5. 完整Socket代码

服务端:

from socket import *
from time import ctime

HOST = 'localhost'
PORT = 10001
ADDRESS = (HOST, PORT)

serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(ADDRESS)
serverSocket.listen(5)

while True:
    print("等待客户端连接...")
    clientSocket, address = serverSocket.accept()
    print(address, "已经成功连接至本服务器")

    while True:
        data = clientSocket.recv(1024)
        if not data:
            break

        replyMsg = data.decode() + "[" + ctime() + ']'
        clientSocket.send(replyMsg.encode())

    clientSocket.close()
serverSocket.close()

客户端:

from socket import *
from time import ctime

HOST = 'localhost'
PORT = 10001
ADDRESS = (HOST, PORT)

clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect(ADDRESS)

while True:
    data = input('请输入消息:')
    if not data:
        break

    clientSocket.send(data.encode())
    data = clientSocket.recv(1024)
    if not data:
        break

    print("服务器返回的消息是:", data.decode('utf-8'))

clientSocket.close()









本文转自 yuanzhitang 51CTO博客,原文链接:http://blog.51cto.com/yuanzhitang/2060790,如需转载请自行联系原作者
目录
相关文章
|
13天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
13天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
2月前
|
网络协议 安全 开发者
Python 中的 Socket 编程
Python 中的 Socket 编程
44 4
|
3月前
|
Python
中文csv文本编码转utf8那些事 - python实现
中文csv文本编码转utf8那些事 - python实现
35 1
|
3月前
|
网络协议 程序员 Python
揭秘Python网络编程:深入理解Socket通信
在当今信息时代,网络通信已经成为人们生活中不可或缺的一部分。而Python作为一种高效、易用的编程语言,自然也能够很好地支持网络编程和Socket通信。本文将介绍Python网络编程与Socket通信的相关知识,包括Socket通信模型、Socket编程接口、网络套接字等内容。
|
3月前
|
网络协议 开发者 Python
Python网络编程与Socket通信:连接世界的无限可能
在当今数字化时代,Python作为一种强大的编程语言,通过网络编程与Socket通信为我们打开了连接世界的无限可能。本文将深入探讨Python网络编程的基础知识、Socket通信的原理以及实际应用,帮助读者更好地理解并运用这一技术。
|
1月前
|
存储 移动开发 算法
Python怎么将图片转换成base64编码
Python怎么将图片转换成base64编码
27 0
|
3月前
|
数据挖掘 开发工具 Python
基于Python开发的企业编码生成系统(源码+可执行程序+程序配置说明书+程序使用说明书)
基于Python开发的企业编码生成系统(源码+可执行程序+程序配置说明书+程序使用说明书)
|
12天前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。
|
16天前
|
Python
Python网络编程基础(Socket编程)UDP服务器编程
【4月更文挑战第8天】Python UDP服务器编程使用socket库创建UDP套接字,绑定到特定地址(如localhost:8000),通过`recvfrom`接收客户端数据报,显示数据长度、地址和内容。无连接的UDP协议使得服务器无法主动发送数据,通常需应用层实现请求-响应机制。当完成时,用`close`关闭套接字。