码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2018-01-14 17:46:16      阅读:1507      评论:0      收藏:0      [点我收藏+]

标签:ror   import   python3   std   ima   ado   from   介绍   知识   

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

软件环境

Python: 3.6.0
库: socket

问题初见

仿照书中的代码(中文版 55-56页) 加上自己的一点改动在我的环境中不能运行,总是报这个错误:
技术分享图片

这里是我的客户端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, 怎么破?

研究错误 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

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

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

官方文档对Socket的说明:
https://docs.python.org/3/library/socket.html
socket.send(bytes[, flags])

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

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

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

clientSocket.send(data.encode())

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

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

encode() 和 decode()

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

默认的encoding是 utf-8

官方文档:
str.encode()
bytes.decode()

完整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()

《Python核心编程》第三版原始代码P55-56在Python3中并不能运行的问题,算不算一个错误呢?

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

标签:ror   import   python3   std   ima   ado   from   介绍   知识   

原文地址:http://blog.51cto.com/yuanzhitang/2060790

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!