前言:打好基礎,加油!!!,給大家安利,《Python核心編程》這本書真的不錯,小白不要看,適合有一定基礎後再看!!!強推!!!我這個是個簡單的讀書筆記,目的只是爲了讓自己養成一種記錄的習慣,畢竟咋也只是剛剛開始,沒那麼多自己能寫的東西,希望通過這種方式督促自己的學習;
文章目錄
socket
基本用法
要創建套接字,必須使用socket.socket()
用法:
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
,代表TCP與IP,其他參數自行百度,
socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
,代表UDP/IP
所有套接字都是通過使用 socket.socket()函數來創建的,並且它們必須綁定到一個本地地址,調用 accept()函數之後,就開啓了一個簡單的(單線程)服務器,它會等待客戶端的連接。默認情況下,accept()是阻塞的,這意味着執行將被暫停,直到一個連接到達。
關於listen(n)
listen(n)傳入的值, n表示的是服務器拒絕(超過限制數量的)連接之前,操作系統可以掛起的最大連接數量。n也可以看作是"排隊的數量"
一般情況下,一個進程只有一個主線程(也就是單線程),那麼socket允許的最大連接數爲: n + 1
如果服務器是多線程,比如上面開了2個線程,那麼socket允許的最大連接數就是: n + 2
換句話說:排隊的人數(就是那個n) + 正在就餐的人數(服務器正在處理的socket連接數) = 允許接待的總人數(socket允許的最大連接數)
內置方法
一個簡單的例子
服務端:
import socket
from time import ctime
HOST = "0.0.0.0"
PORT = 8000
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen()
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
print("...connected from:", addr)
data = tcpCliSock.recv(BUFSIZ).decode("utf-8")
if not data:
break
print(data)
tcpCliSock.send(f'[{ctime()}] {data}'.encode("utf-8"))
tcpCliSock.close()
客戶端:
import socket
HOST = "127.0.0.1"
PORT = 8000
BUFSIZ = 1024
ADDR = (HOST, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
client.send("Y4tacker".encode("utf-8"))
data = client.recv(BUFSIZ).decode("utf-8")
print(data)
解釋:
HOST 變量是空白的,這是對 bind()方法的標識,表示它可以使用任何可用的地址,當然也可以寫成0.0.0.0
SocketServer 模塊
SocketServer 是標準庫中的一個高級模塊(Python 3.x 中重命名爲socketserver),它的目標是簡化很多樣板代碼,它們是創建網絡客戶端和服務器所必需的代碼。這個模塊中有爲你創建的各種各樣的類
SocketServer 模塊類
創建 SocketServer TCP 服務端
Add:坑死了,在python3裏面是小寫!!!坑死了,記得encode!!!
from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)
from time import ctime
HOST = ''
PORT = 8000
ADDR = (HOST, PORT)
# 當接收到一個來自客戶端的消息時,它就會調用 handle()方法。而 StreamRequestHandler
# 類將輸入和輸出套接字看作類似文件的對象,因此我們將使用 readline()來獲取客戶端消息,
# 並利用 write()將字符串發送回客戶端
class MyRequestHandler(SRH):
def handle(self):
print('connected from:', self.client_address)
self.wfile.write(f'[{ctime()}] {self.rfile.readline().decode("utf-8")}'.encode("utf-8"))
tcpServ = TCP(ADDR, MyRequestHandler)
print('waiting for connection...')
tcpServ.serve_forever()
創建 SocketServer TCP 客戶端
坑死了,記得每個send的消息體最後加上\r\n
不然就接收不到消息
import socket
HOST = "127.0.0.1"
PORT = 8000
BUFSIZ = 1024
ADDR = (HOST, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
client.send("Y4tacker\r\n".encode("utf-8"))
data = client.recv(BUFSIZ).decode("utf-8")
print(data)
Twisted 框架介紹
Twisted 是一個完整的事件驅動的網絡框架,利用它既能使用也能開發完整的異步網絡應用程序和協議。它提供了大量的支持來建立完整的系統,包括網絡協議、線程、安全性和身份驗證、聊天/ IM、DBM 及 RDBMS 數據庫集成、Web/因特網、電子郵件、命令行參數、GUI 集成工具包等。
服務端:
from twisted.internet import protocol, reactor
from time import ctime
PORT = 8000
class TSServProtocol(protocol.Protocol):
def connectionMade(self):
clnt = self.clnt = self.transport.getPeer().host
print('...connected from:', clnt)
def dataReceived(self, data):
self.transport.write(f'[{ctime()}] [{data.decode("utf-8")}]'.encode("utf-8"))
factory = protocol.Factory()
factory.protocol = TSServProtocol
print('waiting for connection...')
reactor.listenTCP(PORT, factory)
reactor.run()
客戶端:
from twisted.internet import protocol, reactor
HOST = '127.0.0.1'
PORT = 8000
class TSClntProtocol(protocol.Protocol):
def sendData(self):
data = 'ywh'
print(f'...sending {data}...')
self.transport.write(data.encode("utf-8"))
def connectionMade(self):
self.sendData()
def dataReceived(self, data):
print(data)
self.sendData()
class TSCLntFactory(protocol.ClientFactory):
protocol = TSClntProtocol
clientConnectionLost = clientConnectionFailed = lambda self, connector, reason: reactor.stop()
reactor.connectTCP(HOST, PORT, TSCLntFactory())
reactor.run()