實現代碼(C#) 1、發送GET指令 2、接收批量回覆 3、 結果: 代碼重構 1、發送指令 2、接收回覆 3、GET和SET指令 4、重構後的代碼 是不是簡潔很多??? 5、結果 ...
實現代碼(C#)
1、發送GET指令
string keyGet = "SetKeyTest"; // 設置 的key StringBuilder sbSendGet = new StringBuilder(); sbSendGet.Append("*2\r\n"); // 參數數量 3 string cmdGet = "GET"; sbSendGet.Append("$" + Encoding.UTF8.GetBytes(cmdGet).Length + "\r\n"); // 參數1的長度 sbSendGet.Append(cmdGet + "\r\n");// 參數1( GET指令 ) sbSendGet.Append("$" + Encoding.UTF8.GetBytes(keyGet).Length + "\r\n"); // 參數2的長度 sbSendGet.Append("" + keyGet + "\r\n");// 參數2(GET 的 KEY) Console.WriteLine("發送的命令:"); Console.Write(sbSendGet.ToString()); byte[] dataGet = Encoding.UTF8.GetBytes(sbSendGet.ToString()); // 把請求轉換為byte數組 s.Send(dataGet); // 發送指令
2、接收批量回覆
byte[] resultGET = new byte[512]; int resultGetLength = s.Receive(resultGET); // 接收回覆 // 根據接收到的數據長度重新組裝一個結果 byte[] newResultGet = new byte[resultGetLength]; for (int i = 0; i < resultGetLength; i++) { newResultGet[i] = resultGET[i]; } string strGetResult = Encoding.UTF8.GetString(newResultGet); // 把結果轉換為string Console.Write("獲取的值:"+strGetResult);
3、 結果:
代碼重構
1、發送指令
/// <summary> /// 發送指令 /// </summary> /// <param name="client"></param> /// <param name="datas"></param> /// <returns></returns> public static string SendCmd(this Socket client, params byte[][] datas) { client.Send(Encoding.UTF8.GetBytes("*" + datas.Length + "\r\n")); for (int i = 0; i < datas.Length; i++) { client.Send(Encoding.UTF8.GetBytes("$" + datas[i].Length)); client.Send(Encoding.UTF8.GetBytes("\r\n")); client.Send(datas[i]); client.Send(Encoding.UTF8.GetBytes("\r\n")); } return Reply(client); }
2、接收回覆
/// <summary> /// 接收回覆 /// </summary> /// <param name="client"></param> /// <returns></returns> public static string Reply(Socket client) { BufferedStream s = new BufferedStream(new NetworkStream(client)); int b = s.ReadByte(); // 讀取第一個位元組 string result; switch (b) { // 狀態回覆(status reply)的第一個位元組是 "+" case '+': result = ReadLine(s); return "+"+result; // 錯誤回覆(error reply)的第一個位元組是 "-" case '-': result = ReadLine(s); throw new Exception(result); // 拋出異常 // 整數回覆(integer reply)的第一個位元組是 ":" case ':': result = ReadLine(s); return ":" + result; // 批量回覆(bulk reply)的第一個位元組是 "$" case '$': result = ReadLine(s); // 先讀取數據位元組數 Console.WriteLine("$"+result); int count = int.Parse(result); // 如果被請求的值不存在, 那麼批量回覆會將特殊值 -1 用作回覆的長度值, if (count == -1) { return null; } result = ReadByLength(s, count); Console.WriteLine(result); return result; // 多條批量回覆(multi bulk reply)的第一個位元組是 "*" case '*': result = ReadLine(s); // 先讀取數據行數 Console.WriteLine("*" + result); int rows = int.Parse(result); StringBuilder sb = new StringBuilder(); for (int i = 0; i < rows; i++) { result = ReadLine(s); sb.AppendLine(result); result = ReadLine(s); sb.AppendLine(result); } Console.WriteLine(sb); return sb.ToString(); default: break; } return ""; } /// <summary> /// 按長度讀取 /// </summary> /// <param name="s"></param> /// <param name="l"></param> /// <returns></returns> public static string ReadByLength(BufferedStream s, long l) { byte[] bytes = new byte[l]; var r= s.Read(bytes,0,(int)l); return Encoding.UTF8.GetString(bytes); } /// <summary> /// 按行讀取 /// </summary> /// <param name="s"></param> /// <returns></returns> public static string ReadLine(BufferedStream s) { StringBuilder sb = new StringBuilder(); int b = 0; while ((b = s.ReadByte()) != -1) { if (b == '\r') { if ((b = s.ReadByte()) != -1) { if (b == '\n') { break; } else { sb.Append('\r'); } } else { break; } } sb.Append((char)b); } return sb.ToString(); }
3、GET和SET指令
public static bool Set(this Socket client, string key, string value) { return Set(client, key, Encoding.UTF8.GetBytes(value)); } public static bool Set(this Socket client, string key, byte[] value) { string result = SendCmd(client, Encoding.UTF8.GetBytes("SET"), Encoding.UTF8.GetBytes(key), value); Console.WriteLine(result); return result == "+OK"; // 如果+OK 則表示設置成功! //string } public static string Get(this Socket client, string key) { return SendCmd(client, Encoding.UTF8.GetBytes("GET"), Encoding.UTF8.GetBytes(key)); //string }
4、重構後的代碼
#region SET string key = "SetKeyTest"; // 設置 的key string value = "設置的值"; // 設置的值 var result = s.Set(key, value); Console.WriteLine(result ? "設置成功!" : "設置失敗!"); // 判斷設置是否成功 #endregion #region 發送指令Get string keyGet = "SetKeyTest"; // 設置 的key var resultGet = s.Get(keyGet); // 發送指令 Console.Write("獲取的值:" + resultGet); #endregion
是不是簡潔很多???
5、結果