zoukankan      html  css  js  c++  java
  • Python 3中套接字编程中遇到TypeError: 'str' does not support the buffer interface的解决办法

    转自:http://blog.csdn.net/chuanchuan608/article/details/17915959

    目前正在学习python,使用的工具为python3.2.3。发现3x版本和2x版本有些差异,在套接字编程时,困扰了我很久,先将python核心编程书中的例子

    代码如下:

    服务器端:

        # Echo server program  
        from socket import *  
        from time import ctime  
          
        HOST = ''                 # Symbolic name meaning all available interfaces  
        PORT = 50007              # Arbitrary non-privileged port  
        BUFSIZE = 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(BUFSIZE)  
                if not data:  
                    break  
                tcpCliSock.send(('[%s] %s' % (ctime(), data)))  
          
                tcpCliSock.close()  
        tcpSerSock.close()  


    客户端

        # Echo client program  
        from socket import*  
          
        HOST = '127.0.0.1'  
        PORT = 50007              # The same port as used by the server  
        BUFSIZE = 1024  
        ADDR = (HOST, PORT)  
          
        tcpCliSock = socket(AF_INET, SOCK_STREAM)  
        tcpCliSock.connect(ADDR)  
        while True:  
            data = input('> ')  
            if not data:  
                break  
            tcpCliSock.send(data)  
            data = tcpCliSock.recv(BUFSIZE)  
            if not data:  
                break  
            print(data)  
              
        tcpCliSock.close()  

    报错:

       TypeError:'str' does not support the buffer interface

    找问题找了好久,在StackOverflow上发现有人也出现同样的问题,并一个叫Scharron的人提出了解答:

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

    So, now, whenever you have a unicode stringthat you need to use as a byte string, you need toencode() 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 enclosedstrings. 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()

    同时我看了一下python帮助文档:

    Codec.encode(input[, errors])

    Encodes the object input and returns atuple (output object, length consumed). Encoding converts a string object to abytes object using a particular character set encoding

    Codec.decode(input[, errors])

    Decodes the object input and returns atuple (output object, length consumed). Decoding converts a bytes objectencoded using a particular character set encoding to a string object.

    input must be a bytes object or one whichprovides the read-only character buffer interface – for example, buffer objectsand memory mapped files.

    套接字的成员函数send

    socket.send(bytes[, flags]) 形参为字节类型

    socket.recv(bufsize[, flags]) Receive datafrom the socket. The return value is abytes object representing the data received.

     所以修正后代码如下:

    服务器端:

       # Echo server program  
        from socket import *  
        from time import ctime  
          
        HOST = ''                 # Symbolic name meaning all available interfaces  
        PORT = 50007              # Arbitrary non-privileged port  
        BUFSIZE = 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(BUFSIZE).decode()  
                if not data:  
                    break  
                tcpCliSock.send(('[%s] %s' % (ctime(), data)).encode())  
          
                tcpCliSock.close()  
        tcpSerSock.close()  

    客服端:

    # Echo client program  
    from socket import*  
      
    HOST = '127.0.0.1'  
    PORT = 50007              # The same port as used by the server  
    BUFSIZE = 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(BUFSIZE).decode()  
        if not data:  
            break  
        print(data)  
          
    tcpCliSock.close() 

     


    运行结果: 达到预期

    在使用这些函数时想当然去用,没有去查找帮助文档,没有弄清楚传参类型,可能是一个例题,没有注意这些,但是得吸取教训。

    同样的在udp的情况下:修正过的

    服务器端:

        from socket import *  
        from time import ctime  
          
        HOST = '';  
        PORT = 21546  
        BUFSIZE = 1024  
        ADDR = (HOST, PORT)  
          
        udpSerSock = socket(AF_INET, SOCK_DGRAM)  
        udpSerSock.bind(ADDR)  
          
        while True:  
            print('waiting for message...')  
            data, addr = udpSerSock.recvfrom(BUFSIZE)  
            udpSerSock.sendto(('[%s] %s' %(ctime(), data.decode())).encode(), addr)  
            print('...received from and returned to:', addr)  
          
        udpSerSock.close()  


    客户端:

        from socket import *  
          
        HOST = 'localhost'  
        PORT = 21567  
        BUFSIZE = 1024  
        ADDR = (HOST, PORT)  
          
        while True:  
            tcpCliSock = socket(AF_INET, SOCK_STREAM)  
            tcpCliSock.connect(ADDR)  
            data = input('> ')  
            if not data:  
                break  
            tcpCliSock.send(('%s
    ' % data).encode())  
            data = tcpCliSock.recv(BUFSIZE).decode()  
            if not data:  
                break  
            print(data.strip())  
        tcpCliSock.close()  

    使用socketserver模块:

    服务器端:

        #TsTservss.py  
        from socketserver import TCPServer as TCP, StreamRequestHandler as SRH  
        from time import ctime  
          
          
        HOST = ''  
        PORT = 21567  
        ADDR = (HOST, PORT)  
          
        class MyRequestHandler(SRH):  
            def handle(self):  
                print('...connected from:', self.client_address)  
                self.wfile.write(('[%s] %s' %(ctime(), self.rfile.readline().decode())).encode())  
          
        tcpServ = TCP(ADDR, MyRequestHandler)  
        print('waiting for connection...')  
        tcpServ.serve_forever()  


    客户端:

        from socket import *  
          
        HOST = 'localhost'  
        PORT = 21567  
        BUFSIZE = 1024  
        ADDR = (HOST, PORT)  
          
        while True:  
            tcpCliSock = socket(AF_INET, SOCK_STREAM)  
            tcpCliSock.connect(ADDR)  
            data = input('> ')  
            if not data:  
                break  
            tcpCliSock.send(('%s
    ' % data).encode())  
            data = tcpCliSock.recv(BUFSIZE).decode()  
            if not data:  
                break  
            print(data.strip())  
        tcpCliSock.close() 
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/xjin/p/4015286.html
Copyright © 2011-2022 走看看