Python 3のソケットプログラムでType Errorに遭遇しました.'str'does not support the buffer interfaceの解決方法
17648 ワード
回転:http://blog.csdn.net/chuanchuan608/article/details/17915959
今はpythonを勉強しています.使う道具はpython 3.2.3です.3 xバージョンと2 xバージョンの違いを発見しました.ソケットのプログラミングの時、長い間困っていました.まずpythonコアプログラミング書の例を紹介します.
コードは以下の通りです
サーバ端:
クライアント
エラー:
TypeError:'str'does not support the buffer interface
問題を探して長い間探しましたが、StockOverflowで同じ問題がある人を見つけました.Schronという人が答えを出しました.
In python 3、bytes strigs and unicode strings are now two different types.Since sockets are not aware of string encodings、they are using raw bytes stings、that have a slightly differentince from.
So,now,whenever you have a unicode stingthat 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 reglar(python 2.x)string.
Unicode strigs ares enclosed stregs.Bytes strigs are b「」 enclosed streings
When you use clientsockett.send(data)、replace it by clientsockete.send(data.encode).When you get datausing data=client_sockett.recv(512)、replace it by data=client_sockett.recv(512).decode()
同時に私はpythonヘルプ文書を見ました.
Codec.encode(input[,errors])
Encodes the object input and returns apartuple.Ength consumed.Encoding converts a string object to abrytes using a particular character set encoding
Codec.decode(input[,errors])
Decodes the object input and returns apple.Decoding converts a bytes oject encoded using a particular set encoding to a string object.
input must be a bytes oject or one whichprovides the read-only character buffer interface–for example,buffer oject said memory mapped files.
ソケットのメンバー関数send
socket.send(bytes[,flags])はバイトタイプとして登録されています.
sockett.recv(bufsize[,flags])Receive datafrom the socket.The return value is abytes object representing the data received.
修正後のコードは以下の通りです.
サーバ端:
サービス:
運転結果:予想通り
これらの関数を使う時はもちろん使いたいです.ヘルプドキュメントを探していません.タイプがよく分かりません.例の問題かもしれません.これらに注意していませんが、教訓をくみ取ります.
同じudpの場合:修正しました.
サーバ端:
クライアント:
socketserverモジュールを使う:
サーバ端:
クライアント:
今はpythonを勉強しています.使う道具はpython 3.2.3です.3 xバージョンと2 xバージョンの違いを発見しました.ソケットのプログラミングの時、長い間困っていました.まず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
問題を探して長い間探しましたが、StockOverflowで同じ問題がある人を見つけました.Schronという人が答えを出しました.
In python 3、bytes strigs and unicode strings are now two different types.Since sockets are not aware of string encodings、they are using raw bytes stings、that have a slightly differentince from.
So,now,whenever you have a unicode stingthat 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 reglar(python 2.x)string.
Unicode strigs ares enclosed stregs.Bytes strigs are b「」 enclosed streings
When you use clientsockett.send(data)、replace it by clientsockete.send(data.encode).When you get datausing data=client_sockett.recv(512)、replace it by data=client_sockett.recv(512).decode()
同時に私はpythonヘルプ文書を見ました.
Codec.encode(input[,errors])
Encodes the object input and returns apartuple.Ength consumed.Encoding converts a string object to abrytes using a particular character set encoding
Codec.decode(input[,errors])
Decodes the object input and returns apple.Decoding converts a bytes oject encoded using a particular set encoding to a string object.
input must be a bytes oject or one whichprovides the read-only character buffer interface–for example,buffer oject said memory mapped files.
ソケットのメンバー関数send
socket.send(bytes[,flags])はバイトタイプとして登録されています.
sockett.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\r
' % 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\r
' % data).encode())
data = tcpCliSock.recv(BUFSIZE).decode()
if not data:
break
print(data.strip())
tcpCliSock.close()