python----网络编程(TCP通讯)

Posted 光を追うのCaius

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python----网络编程(TCP通讯)相关的知识,希望对你有一定的参考价值。

python----网络编程(TCP通讯)

笔者在学习Python核心编程(第三版)这本书籍的时候

在章节网络编程 2.4.1----TCP服务端和客户端里面

尝试按照书籍编写TCP服务端和客户端的程序

书籍例子如下

TCP服务端

#coding=utf-8
#创建TCP服务器
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)  #监听连接,传入连接请求的最大数

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客户端

#coding=utf-8

from socket import *

HOST = localhost #  or ‘localhost‘
PORT = 21567
BUFSIZ = 1024
ADDR=(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() 

 

在启动服务端后,再启动客户端去连接服务器,输入信息,在服务器会返回报错:

TypeError: a bytes-like object is required, not ‘str’ 

 

笔者纠结了很久,在百度上搜索了相关的文章,看到了作者“MrYx”的一篇文章

https://blog.csdn.net/yexiaohhjk/article/details/68066843

里面有说道

In python 3, bytes strings and unicode strings are now two different types. Since sockets are not aware of string encodings, they are using raw bytes strings, that have a slightly different interface from unicode strings.

So, now, whenever you have a unicode string that you need to use as a byte string, you need to encode() 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 enclosed strings. 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()


这里大致的意思就是,Pyhon3之后,bytes strings 和 unicode strings 是两种不同的字符类型。如果想要将unicode strings变成bytes strings,我们需要用encode()这种方式去对其进行转码。反之,我们则需要用到decode()。而在书籍的例子里面,在关于变量data,并没有考虑到这点。我们从socket里面接受或者发送的数据,应该是bytes类型的,但是我们在程序里面编辑的时候,需要的字符类型是unicode的,因此,我们需要对书籍的例子作出修改。

 

修改如下

TCP服务端

#!/usr/bin/python3
#-*- coding -*-

from socket import *
from time import ctime

HOST = ‘‘
PORT = 21571
BUFSIZ = 1024
ADDR = (HOST,PORT)

tcpSerSock = socket(AF_INET,SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
    print (waiting for connection)
    tcpCliSock ,addr = tcpSerSock.accept()
    print (...connected from:,addr)

    while True:
        data = tcpCliSock.recv(BUFSIZ).decode()
        if not data:
            break
        tcpCliSock.send(([%s] %s %(ctime(),data)).encode())

    tcpCliSock.close()
tcpCliSock.close()

 

TCP客户端

#!/usr/bin/python3
#-*- coding -*-

from  socket import *

HOST = 127.0.0.1
PORT = 21571
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()

 

本文参考

https://blog.csdn.net/yexiaohhjk/article/details/68066843


以上是关于python----网络编程(TCP通讯)的主要内容,如果未能解决你的问题,请参考以下文章

PYTHON-网络通信 TCP

TCP网络协议的三次握手及代码释义

python网络编程 - tcp

TCP网络通讯如何解决分包粘包问题(有模拟代码)

Python socket实现服务器客户端聊天通讯

Python 之 Socket编程(TCP/UDP)