haoop rpc服务端读取数据包源码解析注释
来源:互联网 发布:2007版数据透视表教程 编辑:程序博客网 时间:2024/06/03 05:40
RPC包格式:
这图是从别人那拿过来的 留着自己看,主要是对如下这段代码的理解有帮助:
/** * 请求报文:4字节hrpc + 1字节Current_version + 1字节authMethod * 4字节Header_len + connection_header * 4字节Data_len + call.id + writable * * connection_header长度不定 call.id + writable长度不等 * * 返回报文:call.id + status.state + writable * errorClass + error * @return * @throws IOException * @throws InterruptedException */ public int readAndProcess() throws IOException, InterruptedException { while (true) { /* Read at most one RPC. If the header is not read completely yet * then iterate until we read first RPC or until there is no data left. */ int count = -1; //读取hrpc信息 if (dataLengthBuffer.remaining() > 0) { count = channelRead(channel, dataLengthBuffer); if (count < 0 || dataLengthBuffer.remaining() > 0) return count; } if (!rpcHeaderRead) {//一次连接 只会读一次 //Every connection is expected to send the header. if (rpcHeaderBuffer == null) { rpcHeaderBuffer = ByteBuffer.allocate(2); } count = channelRead(channel, rpcHeaderBuffer); if (count < 0 || rpcHeaderBuffer.remaining() > 0) { return count; } //读取current_version信息 int version = rpcHeaderBuffer.get(0); //读取authMethod(认证方法)信息 byte[] method = new byte[] {rpcHeaderBuffer.get(1)}; authMethod = AuthMethod.read(new DataInputStream(new ByteArrayInputStream(method))); dataLengthBuffer.flip(); if (!HEADER.equals(dataLengthBuffer) || version != CURRENT_VERSION) { //Warning is ok since this is not supposed to happen. LOG.warn("Incorrect header or version mismatch from " + hostAddress + ":" + remotePort + " got version " + version + " expected version " + CURRENT_VERSION); return -1; } dataLengthBuffer.clear(); if (authMethod == null) { throw new IOException("Unable to read authentication method"); } if (isSecurityEnabled && authMethod == AuthMethod.SIMPLE) { AccessControlException ae = new AccessControlException("Authentication is required"); setupResponse(authFailedResponse, authFailedCall, Status.FATAL, null, ae.getClass().getName(), ae.getMessage()); responder.doRespond(authFailedCall); throw ae; } if (!isSecurityEnabled && authMethod != AuthMethod.SIMPLE) { doSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslRpcServer.SWITCH_TO_SIMPLE_AUTH), null, null); authMethod = AuthMethod.SIMPLE; // client has already sent the initial Sasl message and we // should ignore it. Both client and server should fall back // to simple auth from now on. skipInitialSaslHandshake = true; } if (authMethod != AuthMethod.SIMPLE) { useSasl = true; } rpcHeaderBuffer = null; rpcHeaderRead = true; continue; } //读取connection连接信息及真正的Data信息 if (data == null) { dataLengthBuffer.flip(); dataLength = dataLengthBuffer.getInt(); if (dataLength == Client.PING_CALL_ID) {//如果此RPC调用为ping则 直接返回 if(!useWrap) { //covers the !useSasl too dataLengthBuffer.clear(); return 0; //ping message } } if (dataLength < 0) { LOG.warn("Unexpected data length " + dataLength + "!! from " + getHostAddress()); } data = ByteBuffer.allocate(dataLength); } count = channelRead(channel, data); //当data没有空位置时 说明已经读完 if (data.remaining() == 0) { dataLengthBuffer.clear(); data.flip(); if (skipInitialSaslHandshake) { data = null; skipInitialSaslHandshake = false; continue; } boolean isHeaderRead = headerRead; if (useSasl) { saslReadAndProcess(data.array()); } else {//此处具体处理Data信息及Header信息 processOneRpc(data.array()); } data = null; if (!isHeaderRead) {//如果只读取了Header信息 继续循环读取Data信息 continue; } } return count; } }
private void processOneRpc(byte[] buf) throws IOException, InterruptedException { if (headerRead) {//读取Data信息 processData(buf); } else {//读取Header信息 processHeader(buf); headerRead = true; if (!authorizeConnection()) { throw new AccessControlException("Connection from " + this + " for protocol " + header.getProtocol() + " is unauthorized for user " + user); } } }
private void processData(byte[] buf) throws IOException, InterruptedException { DataInputStream dis = new DataInputStream(new ByteArrayInputStream(buf)); int id = dis.readInt(); // try to read an id if (LOG.isDebugEnabled()) LOG.debug(" got #" + id); Writable param = ReflectionUtils.newInstance(paramClass, conf);//read param param.readFields(dis); Call call = new Call(id, param, this); callQueue.put(call); // queue the call; maybe blocked here incRpcCount(); // Increment the rpc count }
/// Reads the connection header following version private void processHeader(byte[] buf) throws IOException { DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf)); header.readFields(in); try { String protocolClassName = header.getProtocol(); if (protocolClassName != null) { protocol = getProtocolClass(header.getProtocol(), conf); } } catch (ClassNotFoundException cnfe) { throw new IOException("Unknown protocol: " + header.getProtocol()); } UserGroupInformation protocolUser = header.getUgi(); if (!useSasl) { user = protocolUser; if (user != null) { user.setAuthenticationMethod(AuthMethod.SIMPLE.authenticationMethod); } } else { // user is authenticated user.setAuthenticationMethod(authMethod.authenticationMethod); //Now we check if this is a proxy user case. If the protocol user is //different from the 'user', it is a proxy user scenario. However, //this is not allowed if user authenticated with DIGEST. if ((protocolUser != null) && (!protocolUser.getUserName().equals(user.getUserName()))) { if (authMethod == AuthMethod.DIGEST) { // Not allowed to doAs if token authentication is used throw new AccessControlException("Authenticated user (" + user + ") doesn't match what the client claims to be (" + protocolUser + ")"); } else { // Effective user can be different from authenticated user // for simple auth or kerberos auth // The user is the real user. Now we create a proxy user UserGroupInformation realUser = user; user = UserGroupInformation.createProxyUser(protocolUser .getUserName(), realUser); // Now the user is a proxy user, set Authentication method Proxy. user.setAuthenticationMethod(AuthenticationMethod.PROXY); } } } }
具体查看链接:http://fengshenwu.com/blog/2012/11/13/hadoop-rpc_develop/
我的hadoop源码(有一些我看代码时留下的注释):https://github.com/heipacker/hadoop-1.0.3-linux
- haoop rpc服务端读取数据包源码解析注释
- 传智---Haoop--(7)--RPC
- Hadoop RPC 源码解析
- VS C++ 服务端解析WebSocket数据包
- Hadoop 源码解析-rpc扩展
- tcp服务端客户端源码及注释
- Hadoop RPC源码解析——RPC框架详解
- HBASE RPC 源码实现及解析
- Golang 1.4 net/rpc server源码解析
- Hadoop源码解析之RPC协议
- hadoop源码解析之RPC分析
- spark源码解析 spark-core之rpc
- Spark2.x---3. RPC源码解析
- python scapy 捕获与解析数据包的源码解析
- kpush源码解析---服务端(alloc server)
- Netty 4源码解析:服务端启动
- TeamTalk服务端源码解析之DB_Server
- smart-rpc服务端
- 半监督分类问题的一个直观示例说明 (An example of the use of semi-supervised classification)
- 黑马程序员-自学笔记-聊天程序(基于Socket,Thread)
- 基于双目视觉编码结构光的三维点云获取
- Vim基础用法_初学篇
- 难得发现个好的免费空间,分享给大家了
- haoop rpc服务端读取数据包源码解析注释
- C#自己编写的Window服务安装成功后启动出现错误
- WF4.0 基础篇 (十二) CancellationScope 取消容器
- 论node.js的express中csrf的随机验证失败的bug
- ios 常用宏
- android有序广播和无序广播的区别
- Unity3D脚本中Start()和Awake()的区别
- POJ 2352数状数组(一维)
- 如何在mysql中实现update字段