亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    redis通信協(xié)議(protocol)

    redis通信協(xié)議(protocol)

    redis的ping pong

    登錄redis cli客戶端后, 輸入ping, 服務(wù)器會(huì)返回pong, 來表示連接狀況是完好的, 也表示了服務(wù)器大體上是正常運(yùn)轉(zhuǎn)的.

    redis通信協(xié)議(protocol)

    其中的第一行是我用docker 啟動(dòng)的客戶端, 大家如果不是docker的話, 自己正常啟動(dòng)redis -cli就行..

    ping之后就會(huì)收到pong

    使用Java socket 來實(shí)現(xiàn) Redis 的ping pong

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務(wù)器寫         os.write("PINGrn".getBytes());           //從redis服務(wù)器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

    返回的結(jié)果如下:

    redis通信協(xié)議(protocol)

    為什么會(huì)有一個(gè) '+'符號(hào) 呢? redis -cli里是沒有這個(gè)加號(hào)的呀?

    這個(gè)和通信協(xié)議有關(guān), 一會(huì)兒再介紹具體的含義. 不過redis -cli只是把這個(gè)'+'符號(hào)吞掉處理了, 沒顯示出來罷了。

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務(wù)器寫         os.write("PINGrn".getBytes());           //從redis服務(wù)器讀,到bytes中         byte[] bytes = new byte[1024];         if(is.read()=='+'){             // to string 輸出一下             int len = is.read(bytes);             System.out.println(new String(bytes,0,len));         }         // else if $         // else if *         // else     }

    這樣就跟redis -cli里的一樣啦.就只是pong了

    redis通信協(xié)議(protocol)

    實(shí)現(xiàn)SET 和 GET

    set:

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務(wù)器寫         os.write("set hello world123rn".getBytes());           //從redis服務(wù)器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

    get:

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.310", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務(wù)器寫         os.write("get hellorn".getBytes());           //從redis服務(wù)器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

    redis通信協(xié)議(protocol)

    解釋上面例子中的+和$符號(hào)

    加號(hào)'+' 是來表示狀態(tài)回復(fù)的, 在redis服務(wù)端向客戶端返回狀態(tài)信息時(shí), 就會(huì)先發(fā)送一個(gè)`+`符號(hào)來開頭.

    接下來是相應(yīng)的狀態(tài)信息, 例如'OK'什么的.

    最后, 要以'rn' 來結(jié)尾… 咱們看一下代碼就明白了

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務(wù)器寫         os.write("set hello world123rn".getBytes());           //從redis服務(wù)器讀,到bytes中         byte[] bytes = new byte[1024];         if (is.read() == '+') {             System.out.println("這是一個(gè)狀態(tài)回復(fù)哦! 怎么知道的呢? `+` 號(hào)就表示 '狀態(tài)回復(fù)' 了");             int len = is.read(bytes);             System.out.println("回復(fù)的狀態(tài)是: " + new String(bytes, 0, len));         }           // 大家想不想看看bytes里面到底有幾個(gè)字符嗎?         System.out.println(Arrays.toString(bytes));         // 輸出的是 [79, 75, 13, 10, 0, 0, 0, 0, 0,....]         // 其中 79 75 是 `OK`         // 其中 13 10 是 `rn`         // 后面的一串0 是 表示沒有后續(xù)內(nèi)容, 已經(jīng)讀完.     }

    $ 表示批量讀取, 一般格式是: $<數(shù)字>, 數(shù)字來表示正文的內(nèi)容的字節(jié)數(shù)

    redis通信協(xié)議(protocol)

    抓包后是這樣的, 客戶端向服務(wù)端發(fā)送了"get hello", 服務(wù)端向客戶端發(fā)送了藍(lán)色的這兩行.

    public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         // 為了解析'rn'方便, 我就用改為字符流了         BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));           // 向redis服務(wù)器寫         os.write("get hellorn".getBytes());           // 緩沖數(shù)組         char[] chars = new char[1024];           //從redis服務(wù)器讀,到bytes中         if (br.read() == '$') {             System.out.println("這是一個(gè)批量回復(fù)哦! 怎么知道的呢? `$` 號(hào)就表示 '批量回復(fù)' 了");             System.out.println("$ 后面會(huì)跟一個(gè)數(shù)字, 來表示正文內(nèi)容的大小");             // readLine直接能判斷'r' 'n'             int len = Integer.parseInt(br.readLine());             System.out.println("$后面跟著的數(shù)字是: " + len + ", 表示正文是" + len + "個(gè)字節(jié), 接下來只要讀取" + len + "個(gè)字節(jié)就好了");               // 接下來只讀取len個(gè)字符就ok了  (其實(shí)單位應(yīng)該是字節(jié), 但是我中途為了readLine省事, 改用了字符流, 個(gè)數(shù)是不變的)             br.read(chars, 0, len);             System.out.println("get到的結(jié)果是: " + new String(chars, 0, len) + ", 數(shù)一數(shù)真的是" + len + "個(gè)字符");         }     }

    Redis通信協(xié)議就只是這樣?

    no!!!剛才客戶端向服務(wù)端發(fā)送的 "get hello" , 這種只是"內(nèi)聯(lián)命令", 而不是Redis真正的通信協(xié)議.

    問: 什么意思呢? 答: 就是說你可以像之前那樣給服務(wù)端發(fā), 服務(wù)器端接受到后, 會(huì)遍歷一遍你發(fā)送的內(nèi)容, 最后根據(jù)空格來分析你所發(fā)的內(nèi)容的含義.

    問: 這樣有什么不好的嗎? 答: 如果這樣的話, 你就把解析的工作交給了服務(wù)器來做, 會(huì)加大服務(wù)器的工作量.

    問: 那怎么樣才是符合規(guī)范的呢? 符合協(xié)議的話真的會(huì)提高服務(wù)器的效率? 答: 首先看一下符合協(xié)議的客戶端和服務(wù)端之間的交互把.如下例子:

    例: set java python ,抓到包之后是這樣的:

    redis通信協(xié)議(protocol)

    紅色是客戶端發(fā)送的內(nèi)容, 藍(lán)色是服務(wù)器端返回的內(nèi)容.

    咱們一起解析一下:

    *3表示 , 客戶端即將發(fā)送3段內(nèi)容

    哪三段呢? 第一段: '$3 SET' 第二段: '$4 java' 第三段: '$6 python'

    更嚴(yán)格地說: 第一段: '$3rnSETrn' 第二段:'$4rnjavarn' 第三段:'$6rnpythonrn'

    $符號(hào)的意思在上一小節(jié)就已經(jīng)提到過了, 表示下文的內(nèi)容的長度, 方便服務(wù)器進(jìn)行讀取.

    例如: $6就已經(jīng)把python的長度給匯報(bào)出來了, 服務(wù)器只需要截取區(qū)間[index, index+6]就好了, 不需要去找空格在什么地方(找空格的時(shí)間復(fù)雜度是O(n), 而$6這種寫法是O(1) )

    Jedis

    其實(shí)Jedis做的工作大體就是把SET key value 這樣的格式轉(zhuǎn)化為下面這種格式, 然后發(fā)到Redis服務(wù)端:

    *3rn $3rn SETrn $3rn keyrn $5rn valuern

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)