reids java客户端jedis 原理

redis 官网:https://redis.io/

jedis的用法,可以在redis的官网最上边一栏的客户端里面就可以找到。

jedis客户端连接redis服务端的大概流程是这样的。

  • 传输层:用于建立与redis的网络通信,传输信息。起到连接的作用
  • 消息协议层:与redis确认RESP协议是否正确,并携带所要传递的数据信息。
  • api操作层:封装客户端api,方便其他人调用。
/**
 * 
* @ClassName: Connection
* @Description: redis源码学习 之 徒手写redis  get、set方法
* @author hsd
* @date 2019年3月7日
*
 */
public class Connection {

	private Socket socket;
	
	private String host;
	
	private int port;
	
	private OutputStream out;
	
	private InputStream in;
	
	public Connection(String host,int port){
		this.port = port;
		this.host = host;
	}
	
	public Connection connection(){
		try {
			socket = new Socket(host,port);
			in = socket.getInputStream();
			out = socket.getOutputStream();
		}  catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this;
	}
	/**
	 * 
	 *@Title: sendcommand   
	 * @Description: 连接redis服务器端 发送数据和命令  
	 * @param: @return      
	 * @return: Connection      
	 * @throws
	 */
	public Connection sendcommand(Protocol.Command command,byte[] ... args){
		connection();
		Protocol.sendCommand(out, command, args);
		return this;
	}
	/**
	 * 
	 *@Title: getStatusCodereply   
	 * @Description: 获取redis返回给jedis客户端的状态码 
	 * @param: @return      
	 * @return: String      
	 * @throws
	 */
	public String getStatusCodereply(){
		byte[] bytes = new byte[1024];
		
		try {
			socket.getInputStream().read(bytes);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new String(bytes);
		
	}
}
/**
 * 
* @ClassName: Client
* @Description: 对外提供api接口的类
* @author hsd
* @date 2019年3月7日
*
 */
public class Client {

	private Connection connect;
	
	public Client(String host,int port){
		this.connect = new Connection(host, port);
	}
	
	public String set(String key,String value){
		
		connect.sendcommand(Protocol.Command.SET,key.getBytes(),value.getBytes());
		
		return connect.getStatusCodereply();
	}
	
	public String get(String key){
		
		connect.sendcommand(Protocol.Command.GET,key.getBytes());
		
		return connect.getStatusCodereply();
	}
}
/**
 * 
* @ClassName: Protocol
* @Description: jedis和redis之间的通讯协议
* @author hsd
* @date 2019年3月7日
*
 */
public class Protocol {

	/**
	 * 创建jedis和redis的通讯协议   resp
	 */
	public static final String DOLLAR_BYTE="$";
	
	public static final String ASTERISK_BYTE="*";
	
	public static final String BLACK_BYTE="\r\n";
	
	/**
	 * 
	 *@Title: sendCommand   
	 * @Description: 拼接、组装数据发送给redis   
	 * @param:       
	 * @return: void      
	 * @throws
	 */
	public static void sendCommand(OutputStream os,Command command,byte[] ... args){
		
		StringBuilder sb = new StringBuilder();
		sb.append(ASTERISK_BYTE).append(args.length+1).append(BLACK_BYTE);
		sb.append(DOLLAR_BYTE).append(command.name().length()).append(BLACK_BYTE);
		sb.append(command.name()).append(BLACK_BYTE);
		for(final byte[] arg : args){
			sb.append(DOLLAR_BYTE).append(arg.length).append(BLACK_BYTE);
			sb.append(new String(arg)).append(BLACK_BYTE);
		}
		try {
			os.write(sb.toString().getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	/**
	 * 
	* @ClassName: Command
	* @Description: 创建一个枚举,用于确定发送消息的类型  是get 还是 set还是key  等等。。。。。
	* @author 胡少东
	* @date 2019年3月7日
	*
	 */
	public static enum Command{
		GET,SET,KEYS
	}
}
/**
 * 
* @ClassName: JedisClientTest
* @Description: TODO(reids的java客戶端的练习)
* @author hsd
* @date 2019年3月7日
*
 */
public class JedisClientTest {

	public static void main(String[] args) {
//		Jedis jedis = new Jedis("127.0.0.1",10001);
//		
//		jedis.set("kobe", "kobe");
//		
//		System.out.println(jedis.get("kobe"));
		Client jedis = new Client("127.0.0.1",6379);
		
		jedis.set("kobe", "kobe-branty");
		System.out.println(jedis.set("kobe", "kobe-branty"));
		
		System.out.println(jedis.get("kobe"));
	}
}
/**
 * 
* @ClassName: Hack
* @Description: 黑客技术,模拟redis服务端,拦截到jedis发送的请求,查看传输协议。
* @author hsd
* @date 2019年3月7日
*
 */
public class Hack {

	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(10001);
			Socket socket = ss.accept();
			byte[] bytes = new byte[1024];
			socket.getInputStream().read(bytes);
			System.out.println(new String(bytes));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

开发是的先后顺序是:

  1. api操作层:Client
  2. 消息协议层:Protocol
  3. 传输层:Connection
  4. 消息协议层需要模拟redis服务器,获取jedis发送的协议:Hack

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值