日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【Redis学习】redis通讯协议

發(fā)布時間:2024/4/14 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Redis学习】redis通讯协议 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

服務是一個較抽象的概念,意在幫助使用者達到某種需求。那么對于網絡服務來說,通常我們可以將其定義為一個運行在操作系統(tǒng)上的程序,使用者通過網絡與其進行交互并得到想要的信息。

客戶端和服務器通過TCP連接來進行數(shù)據(jù)交互,所以它和其它網絡服務一樣有一個協(xié)議。redis服務器接受命令以及命令的參數(shù)。服務器會在接到命令之后對命令進行處理,并將命令的回復傳送到客戶端。具體在網絡層上就是:Redis在TCP端口6379上監(jiān)聽到來的連接,客戶端連接到來時,Redis服務器為此創(chuàng)建一個TCP連接。在客戶端與服務器端之間傳輸?shù)拿總€Redis命令或者數(shù)據(jù)都以\r\n結尾。

redis的通訊協(xié)議包括:消息頭標識和消息行,消息行里可能還有一個數(shù)據(jù)塊大小的描述。redis是以行來劃分的,每行以\r\n結束,且每一行都有一個消息頭。

消息體一共分為5種類型:

(1)[+]表示一個正確的狀態(tài)信息,具體信息是:當前行+后面的字符
(2)[-]表示一個錯誤信息,具體信息是:當前行-后面的字符
(3)[]表示消息體總共有多少行,不包括當前行,后面是具體的行數(shù)
(4)[]數(shù)據(jù)\r\n]表示下一行數(shù)據(jù)長度,不包括換行符\r\n的長度,后面則是對應長度的數(shù)據(jù)
(5)[:]表示返回一個數(shù)值,:后面是相應的數(shù)字字符

redis命令會返回多種不同類型的回復,通過檢查服務器發(fā)回數(shù)據(jù)的第一個字節(jié),可以確定這個回復是什么類型:

(1)狀態(tài)回復的第一個字節(jié)是[+]
(2)錯誤回復的第一個字節(jié)是[-]
(3)整數(shù)回復的第一個字節(jié)是[:]
(4)批量回復的第一個字節(jié)是[$]
(5)多條批量回復的第一個字節(jié)是[*]

具體指令和返回:

1、SET

client : SET MYTEST HELLO

設置MYTEST的值為HELLO。
在redis的通訊協(xié)議上會以空格把命令拆分成三行,得到最終的命令如下:

*3\r\n --消息體總共3行 $3\r\n --下一行數(shù)據(jù)的長度“SET”為3 SET\r\n $6\r\n --下一行數(shù)據(jù)的長度“MYTEST”為6 MYTEST\r\n $5\r\n --下一行數(shù)據(jù)的長度“HELLO”為5 HELLO\r\n

server :
服務端操作成功:+OK\r\n
如果服務端返回錯誤: -錯誤信息\r\n

2、GET

client : GET MYTEST

產生的通訊指令:

*2\r\n $3\r\n GET\r\n $6\r\n MYTEST

server : 如果存在這個key則返回:

$5\r\n HELLO\r\n

3、HKEYS

client : HKEYS MYTEST

以上命令是獲取對應MYTEST有多少個field成員:

*2\r\n $5\r\n HKEYS\r\n $6\r\n MYTEST\r\n

server :
如果不存在任何字段信息:*0\r\n
如果存在一個AGE字段信息:

*1\r\n $2\r\n AGE\r\n

4、HMGET

client : HMGET MYTEST AGE

以上命令是獲取HENRY的QQ信息。

*3\r\n $5\r\n HMGET\r\n $6\r\n MYTEST\r\n $3\r\n AGE\r\n

server :

如果不存在字段值

*1\r\n $-1\r\n

存在字段值

*1\r\n $2\r\n 28\r\n

以上主要列舉Redis普遍處理的一些情況,由于指令太多就不一一列舉了,如果有需要自己實現(xiàn)Client的朋友可以到Redis官方看相關命令文檔。redis官方文檔

練習小程序:通過socket和redis server進行通信

import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.Charset; public class SimpleProtocol {public static void main(String[] args) throws Exception{Socket socket = new Socket();socket.setReuseAddress(true);//空閑時發(fā)送數(shù)據(jù)包,確認服務端狀態(tài)socket.setKeepAlive(true);//關閉Nagle算法,盡快發(fā)送socket.setTcpNoDelay(true);socket.setSoLinger(true, 0);//連接serversocket.connect(new InetSocketAddress("localhost", 6379), 3000);//設置讀取時超時時間socket.setSoTimeout(3000);OutputStream os = socket.getOutputStream();/*** SET 命令* 協(xié)議: array 3個元素 SET simpleKey simpleValue*/os.write(getBytes("*3\\r\\n$3\\r\\nSET\\r\\n$9\\r\\nsimpleKey\\r\\n$11\\r\\nsimpleValue\\r\\n"));os.flush();InputStream is = socket.getInputStream();/*** 解析SET命令的返回結果*/String result = analysisResult(is);System.out.println("SET command response : " + result);System.out.println();/*** GET 命令* 協(xié)議: array 2個元素 GET simpleKey*/os.write(getBytes("*2\\r\\n$3\\r\\nGET\\r\\n$9\\r\\nsimpleKey\\r\\n"));os.flush();/*** 解析GET命令返回結果*/String value = analysisResult(is);System.out.println("GET command response : " + value);is.close();os.close();socket.close();}/*** 解析返回結果* @param is* @return* @throws Exception*/private static String analysisResult(InputStream is) throws Exception{/*** 第一個字節(jié)指定返回的數(shù)據(jù)結構類型*/byte type = (byte)is.read();System.out.println("response type is : " + (char)type);if(type == '+'){//Simple String類型return readCRLF(is);}else if(type == '$'){//Bulk String類型int len = readIntCRLF(is);System.out.println("$ value len : " + len);return readFixedLen(is, len);}return null;}/*** 讀取int值,直到遇到CRLF* @param is* @return* @throws Exception*/private static int readIntCRLF(InputStream is) throws Exception{return Integer.parseInt(readCRLF(is));}/*** 讀取字符串,直到遇到CRLF* @param is* @return* @throws Exception*/private static String readCRLF(InputStream is) throws Exception{byte b = (byte)is.read();StringBuilder sb = new StringBuilder();//不是最后一個輸入字節(jié)時while(b != -1){//判斷是否是CR,如果不是加入sb中if(b != '\\r'){sb.append((char)b);}else{//如果是CR,繼續(xù)讀取一個字節(jié),如果不是LF,報錯byte oneMore = (byte)is.read();if(oneMore != '\\n'){throw new RuntimeException("CRLF error!");}else{break;}}b = (byte)is.read();}return sb.toString();}/*** 讀取固定字節(jié)長度的字符串* @param is* @param len* @return* @throws Exception*/private static String readFixedLen(InputStream is, int len) throws Exception{byte[] bytes = new byte[len];for(int i = 0; i < len; i++){bytes[i] = (byte)is.read();}//CRis.read();//LFis.read();return new String(bytes, "UTF-8");}private static byte[] getBytes(String str) throws Exception{return str.getBytes(Charset.forName("UTF-8"));} }

運行結果;

response type is : +SET command response : OKresponse type is : $$ value len : 11GET command response : simpleValue 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的【Redis学习】redis通讯协议的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。