今天想了解一下,如何用python鏈接到redis。固然,能夠用redis-py
這個現成的包,只需簡單的pip install redis
就能夠很愉快地用操做redis了 好比:python
>>> import redis >>> r = redis.Redis(host='localhost', port=6379, db=0) >>> r.set('foo', 'bar') True >>> r.get('foo') 'bar'
然而,做爲一個喜歡折騰的程序員我確定不知足使用工具,我想了解一下這是如何實現的。 翻了一下redis-py
的源碼,其實就是socket
,因而就想造個簡單的輪子—直接經過socket鏈接到redis 順代瞭解一下socket編成的基本知識和redis-py
的源碼程序員
套接字起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 Unix,即人們所說的 BSD Unix。 所以,有時人們也把套接字稱爲「伯克利套接字」或「BSD 套接字」。一開始,套接字被設計用在同 一臺主機上多個應用程序之間的通信。這也被稱進程間通信或IPC。套接字有兩種(或者稱爲有兩個種族),分別是基於文件型的和基於網絡型的。redis
基於文件類型的套接字家族 - 套接字家族的名字:AF_UNIX unix一切皆文件,基於文件的套接字調用的就是底層的文件系統來取數據,兩個套接字進程運行在同一機器,能夠經過訪問同一個文件系統間接完成通訊數據庫
基於網絡類型的套接字家族 - 套接字家族的名字:AF_INET (還有AF_INET6被用於ipv6,還有一些其餘的地址家族,不過,他們要麼是隻用於某個平臺,要麼就是已經被廢棄,或者是不多被使用,或者是根本沒有實現,全部地址家族中,AF_INET是使用最普遍的一個,python支持不少種地址家族,可是因爲咱們只關心網絡編程,因此大部分時候我麼只使用AF_INET)編程
套接字把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。因此,咱們無需深刻理解tcp/udp協議,socket已經爲咱們封裝好了,咱們只須要遵循socket的規定去編程,寫出的程序天然就是遵循tcp/udp標準的segmentfault
簡直是一把利器(書架上的《Unix網絡編程》卷一:套接字聯網API在召喚我)緩存
服務端服務器
import socket import sys # 建立 socket 對象 serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 獲取本地主機名 host = socket.gethostname() port = 9999 # 綁定端口號 serversocket.bind((host, port)) # 設置最大鏈接數,超事後排隊 serversocket.listen(5) while True: # 創建客戶端鏈接 clientsocket,addr = serversocket.accept() print("鏈接地址: %s" % str(addr)) msg='歡迎關注匿名程序媛!'+ "\r\n" clientsocket.send(msg.encode('utf-8')) clientsocket.close()
客戶端網絡
import socket import sys # 建立 socket 對象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 獲取本地主機名 host = socket.gethostname() # 設置端口號 port = 9999 # 鏈接服務,指定主機和端口 s.connect((host, port)) # 接收小於 1024 字節的數據 msg = s.recv(1024) s.close() print (msg.decode('utf-8'))
服務端套接字函數socket
s.bind() #綁定(主機,端口號)到套接字
s.listen() #開始TCP監聽
s.accept() #被動接受TCP客戶的鏈接,(阻塞式)等待鏈接的到來
客戶端套接字函數
s.connect() #主動初始化TCP服務器鏈接
s.connect_ex() #connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常
公共用途的套接字函數(客戶端和服務端都能使用)
s.recv() #接收TCP數據
s.send() #發送TCP數據(send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完)
s.sendall() #發送完整的TCP數據(本質就是循環調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,循環調用send直到發完)
s.recvfrom() #接收UDP數據
s.sendto() #發送UDP數據
s.getpeername() #鏈接到當前套接字的遠端的地址
s.getsockname() #當前套接字的地址
s.getsockopt() #返回指定套接字的參數
s.setsockopt() #設置指定套接字的參數
s.close() #關閉套接字
因此?如何鏈接到redis呢?
#!/usr/bin/python3 import socket ''' python3 鏈接redis ''' host = '127.0.0.1' port = 6379 buf_size = 1 conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((host, port)) cmd = 'SELECT 2\n'.encode('utf-8') r = conn.sendall(cmd) cmd = 'PING\n'.encode('utf-8') conn.sendall(cmd) while True: res = conn.recv(buf_size) print(res) if not res: break conn.close()
執行一下python3 ./redis_client.py
,就能夠獲得以下返回。
b'+' b'O' b'K' b'\r' b'\n' b'+' b'P' b'O' b'N' b'G' b'\r' b'\n'
咱們鏈接到第二個數據庫,而後ping
了一下,看到redis返回了PONG
^_^
歡迎你們關注個人公衆號 一塊兒挖坑填坑。。