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

最近在看《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中并不能运行的问题,算不算一个错误呢?

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

时间: 2024-10-30 22:30:21

Python3.X Socket 一个编码与解码的坑的相关文章

python3中的编码与解码原理

先看代码 >>> a = '中文' >>> a '中文' >>> print(a) 中文 >>> b = 'English' >>> b 'English' >>> print(b) English 解释编码和解码的过程 >>> aa = a.encode('utf-8') >>> aa b'\xe4\xb8\xad\xe6\x96\x87' >>&g

记录-第一个python3的socket编程--not 'str'

看到这个提示之后,确定了这个问题主要是是字符编码的问题了,那如何解决这个字符编码问题,目前想到的办法就是通过encode和decode来做字符编码转换了. 服务端进程 # cat tcp_server.py  #! /bin/env python3 # -*- coding:utf-8 -*- ''' Created on 2016年12月19日   @author: CC ''' import socket import datetime HOST='0.0.0.0' PORT=3434 s=

python3 unicod,utf-8,gbk的编码和解码中文显示问题

python3的字符编码让人头疼.这个也不是一篇介绍gbk, utf-8, unicode怎么表示英文,中文字符的基础知识总结.网上有很多类似的文章,目前也不需要升入学习到了解各个bit位表示什么含义. 目的:清楚了解为什么在python3不同的编码,解码,windows,linux操作系统下,字符是否能够正确显示. 前提:了解不同编码用不同的二级制编码和长度来表示字符.在python3中,各种字符编码之间的互相转换都要通过unicode作为中间编码转换.gbk转换成unicode,再从unic

由 Python2 和 Python3 中 socket.inet_aton() 实现不同引发的血案

这几天在做一个功能实现的时候,需要把别人用 Python2.6 写好的脚步转成 Python3.4 实现,大部分地方转化都没啥问题,但是在 socket.inet_aton() 转化的过程中出了点问题,花费我不少的精力去解决,先做个记录备忘,同时给后续需要的人做个提醒. 首先说一下,我在解决这个问题前期的思路有点问题,所以请关注最后的总结. 需求目的:把一个 ip 地址使用 socket.inet_aton() 转化后和一个字符串组合,然后算出 MD5. 下面是 Python2.6 的实现代码:

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是

mina的编码和解码以及断包的处理,发送自定义协议,仿qq聊天,发送xml或json和

最近一段时间以来,mina很火,和移动开发一样,异常的火爆.前面写了几篇移动开发的文章,都还不错,你们的鼓励就是我最大的动力.好了,废话少说.我们来看下tcp通讯吧. tcp通讯对于java来说是很简单的.就是socket,也就是大家常说的套接字.大家不要把它看的很难.说白了tcp通讯其实就是数据流的读写.一条输入流,一条输出流.分别复杂发消息和接收消息. 明白了这些,ok,我们来看看我写的例子吧.先看服务器端的测试类的源码: package com.minaqq.test; import co

从Python的角度来看编码与解码

导语: Python2和Python3中,因为默认字符集的不同而造成的麻烦,简直是程序员的梦魇!要彻底告别这个麻烦,就需要从本质上来理解编码和解码. 为什么要有编码? 对于不会英文的中国人来说,将英文翻译成中文,这个就叫做解码:而将中文翻译成英文,自然就是编码了! 这个道理在计算机中同样适用. 计算机只能识别0和1,任何文字对于计算机来说,就是0和1的排列组合.但是我们人类哪看得懂这种0和1的排列组合! 自然就需要将0和1的文字转换为我们能看得懂的文字,比如中文,英文等. 而这种0和1到文字的映

python之is 和 == 的区别//编码和解码

一.is  和  ==  的区别: ==   比较    #比较两边的值 is    比较   #比较的是内存地址 id()是python的一个内置函数,通过id()我们可以查到一个变量表的值在内存中的地址 (只限于数字和字符串是True) #数字小数据池 :    -5~256 1.字符串中如果有特殊字符,那么不会添加到小数池中,他们的内存地址就不一样 字符串中单个*20以内他们的内存一样,超过20个就不会添加到小数据池;单个*以上内存地址就不一样 注意:pycharm是个坑,一个py文件中所

搜索是关键字的编码和解码

学点东西真的是太难了,真心膜拜那种2个礼拜就能搞定一门语言的大神. 今天遇到的问题是,使用搜索接口时,一些网站会为了兼容性,会将搜索的关键字转码.转码后拼接到URL里,然后进行访问. 1.在python3.x中,编码使用的函数是urllib.parse.urlencode(),解码使用的是urllib.parse.unquote() 2.urlencode()的参数形式是kv型的. 3.一个小坑.网页的编码形式可能是不一样的,所以在编码时,不同的网页编码形式下的文本,通过函数得到的值可能是不同的