Python網絡編程(一)
阿新 • • 發佈:2018-03-03
ted port require 需要 sci sock peer required bin
Python對bytes類型的數據用帶b前綴的單引號或雙引號表示:
在bytes中,無法顯示為ASCII字符的字節,用\x##顯示。
反過來,如果我們從網絡或磁盤上讀取了字節流,那麽讀到的數據就是bytes。要把bytes變為str,就需要用decode()方法。
最近在啃《python核心編程(第三版)》,感覺這本書並不是特別的友好,雖然有基於python3提出的改進代碼;但是整書的基準感覺還是在python2.7。所以python3的代碼中還是有較多的錯誤;就比如第二章網絡編程中:
原代碼:
創建TCP服務器
#coding=utf-8 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()
如果我們按照這個代碼跑,python3會報出:TypeError: a bytes-like object is required, not ‘str‘ 的錯誤。當時我就很納悶,python2.7中明明是適用的,怎麽到python3中就為‘str‘了?報錯的原因是tcpCliSock.send(data)傳入的參數應該是bytes類型,而不是str類型。
關於這個的解釋為python3與python2.7中關於編碼解碼的規則不同,請看下面。
關於編碼
(引用自廖雪峰老師的教程)
由於Python的字符串類型是str,在內存中以Unicode表示,一個字符對應若幹個字節。如果要在網絡上傳輸,或者保存到磁盤上,就需要把str變為以字節為單位的bytes。
b‘ABC
純英文的str可以用ASCII編碼為bytes,內容是一樣的,含有中文的str可以用UTF-8編碼為bytes。含有中文的str無法用ASCII編碼,因為中文編碼的範圍超過了ASCII編碼的範圍,Python會報錯。在bytes中,無法顯示為ASCII字符的字節,用\x##顯示。
反過來,如果我們從網絡或磁盤上讀取了字節流,那麽讀到的數據就是bytes。要把bytes變為str,就需要用decode()方法。
修改後的代碼
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('等待連接中')
tcpCliSock, addr = tcpSerSock.accept()
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
tcpCliSock.send(('[%s] %s' % (ctime(), data)).encode())
tcpCliSock.close()
tcpSerSock.close()
from socket import *
HOST = '127.0.0.1'
PORT = 21567
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()
Python網絡編程(一)