用socket鏈接redis

今天想了解一下,如何用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的源碼程序員

socket的歷史

套接字起源於 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在召喚我)緩存

socket基礎使用方法

服務端服務器

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呢?

my-socket-connect-to-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^_^
歡迎你們關注個人公衆號 一塊兒挖坑填坑。。image

相關文章
相關標籤/搜索