热卖商品
新闻详情
初识RPC_周先生丶的博客-CSDN博客
来自 : CSDN技术社区
发布时间:2021-03-24
3、客户端的实现
先构造一个request请求 通过Socket接口将其发送到远端 并接收远端的响应信息 构造成一个response对象。
/** * 客户端 * author z_hh * time 2019年1月7日public class Client { public static void main(String[] args) throws Throwable { // 请求 Request request new Request(); request.setEncode(Encode.UTF8.getValue()); request.setContent( 有缘遇到你 我叫梅西 request.setContentLength(request.getContent().length()); Socket client new Socket( 127.0.0.1 , 8899); // 发送请求 OutputStream output client.getOutputStream(); ProtocolUtil.writeRequest(output, request); // 读取响应数据 InputStream input client.getInputStream(); Response response ProtocolUtil.readResponse(input); System.out.println( 收到响应 response);}4、服务端的实现
接收客户端的请求并打印 然后响应一段内容。
/** * 服务端 * author z_hh * time 2019年1月7日public class Server { public static void main(String[] args) throws Throwable { ServerSocket server new ServerSocket(8899); while (true) { Socket client server.accept(); // 获取请求数据 InputStream input client.getInputStream(); Request request ProtocolUtil.readRequest(input); System.out.println( 收到请求 request); // 组装响应 OutputStream output client.getOutputStream(); Response response new Response(); response.setEncode(Encode.UTF8.getValue()); response.setContent( 你好呀 我叫内马尔 response.setContentLength(response.getContent().length()); ProtocolUtil.writeResponse(output, response);}5、ProtocolUtil的代码
提供四个工具方法 从输入流读取请求、将请求写到输出流、从输入流读取响应、将响应写到输出流。
/** * 协议工具类 * author z_hh * time 2019年1月7日public class ProtocolUtil { public static Request readRequest(InputStream input) throws IOException { // 读取编码 byte[] encodeByte new byte[1]; input.read(encodeByte); byte encode encodeByte[0]; // 读取内容长度 byte[] contentLengthBytes new byte[4]; input.read(contentLengthBytes); int contentLength ByteUtil.bytes2Int(contentLengthBytes); // 读取内容 byte[] contentBytes new byte[contentLength]; input.read(contentBytes); String content if (Encode.GBK.getValue() encode) { content new String(contentBytes, GBK } else { content new String(contentBytes, UTF8 // 组装请求返回 Request request new Request(); request.setEncode(encode); request.setContent(content); request.setContentLength(contentLength); return request; public static void writeRequest(OutputStream output, Request request) throws IOException { // 将request请求写入output output.write(request.getEncode());// output.write(response.getContentLength());// 直接write一个int类型会截取低8位传输 丢弃高24位 output.write(ByteUtil.int2ByteArray(request.getContentLength())); if (Encode.GBK.getValue() request.getEncode()) { output.write(request.getContent().getBytes( GBK } else { output.write(request.getContent().getBytes( UTF8 output.flush(); public static Response readResponse(InputStream input) throws IOException { // 读取编码 byte[] encodeByte new byte[1]; input.read(encodeByte); byte encode encodeByte[0]; // 读取内容长度 byte[] contentLengthBytes new byte[4]; input.read(contentLengthBytes); int contentLength ByteUtil.bytes2Int(contentLengthBytes); // 读取响应 byte[] contentBytes new byte[contentLength]; input.read(contentBytes); String content if (Encode.GBK.getValue() encode) { content new String(contentBytes, GBK } else { content new String(contentBytes, UTF8 // 组装请求返回 Response response new Response(); response.setEncode(encode); response.setContent(content); response.setContentLength(contentLength); return response; public static void writeResponse(OutputStream output, Response response) throws IOException { // 将response响应写入output output.write(response.getEncode());// output.write(response.getContentLength());// 直接write一个int类型会截取低8位传输 丢弃高24位 output.write(ByteUtil.int2ByteArray(response.getContentLength())); if (Encode.GBK.getValue() response.getEncode()) { output.write(response.getContent().getBytes( GBK } else { output.write(response.getContent().getBytes( UTF8 output.flush();}6、ByteUtil的代码
OutputStream中直接写入一个int类型 会截取其低8位 丢弃其高24位。因此 数据发送时 需要将基本类型先转换为字节流。
同理 接收数据时 也需要将字节流转换为基本类型。
/** * byteArray和int互转工具 * author z_hh * date 2019年1月7日public class ByteUtil { * int 转 byteArray * param i * return public static byte[] int2ByteArray(int i) { byte[] result new byte[4]; result[0] (byte) ((i 24) 0xFF); result[1] (byte) ((i 16) 0xFF); result[2] (byte) ((i 8) 0xFF); result[3] (byte) (i 0xFF); return result; * byteArray 转 int * param bytes * return public static int bytes2Int(byte[] bytes) { int num bytes[3] 0xFF; num | ((bytes[2] 8) 0xFF00); num | ((bytes[1] 16) 0xFF0000); num | ((bytes[0] 24) 0xFF000000); return num;}7、编码集
/** * 编码集 * author z_hh * time 2019年1月7日public enum Encode { UTF8(1), GBK(2); private Encode(int c) { this.value private int value; public byte getValue() { return (byte) value;}
这样 一个简单的应用层通信协议算是实现了
参考 《大型分布式网站架构·设计与实践》
接下来 我们将手写一个简单的RPC框架 敬请期待本文链接: http://rpchh.immuno-online.com/view-684792.html
发布于 : 2021-03-24
阅读(0)
最新动态
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24
2021-03-24