死磕rmi之远程对象
远程对象
远程对象是啥
继承了UnicastRemoteObject的对象都可称为远程对象
让一个对象继承UnicastRemoteObject的能力,就是把自己发布出去。
UnicastRemoteObject初始化
构造方法
调用exportObject。
/**
* Creates and exports a new UnicastRemoteObject object using the
* particular supplied port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @param port the port number on which the remote object receives calls
* (if <code>port</code> is zero, an anonymous port is chosen)
* @throws RemoteException if failed to export object
* @since 1.2
*/
protected UnicastRemoteObject(int port) throws RemoteException
{
this.port = port;
exportObject((Remote) this, port);
}
java.rmi.server.UnicastRemoteObject#exportObject(java.rmi.Remote, int)
目的是接受remote call
/**
* Exports the remote object to make it available to receive incoming
* calls, using the particular supplied port.
*
* <p>The object is exported with a server socket
* created using the {@link RMISocketFactory} class.
*
* @param obj the remote object to be exported
* @param port the port to export the object on
* @return remote object stub
* @exception RemoteException if export fails
* @since 1.2
*/
public static Remote exportObject(Remote obj, int port)
throws RemoteException
{
return exportObject(obj, new UnicastServerRef(port));
}
查看一下sun.rmi.server.UnicastServerRef#UnicastServerRef(int)
public class UnicastServerRef extends UnicastRef implements ServerRef, Dispatcher {
这里调用的构造方法
public UnicastServerRef(int var1) {
super(new LiveRef(var1));
this.forceStubUse = false;
this.hashToMethod_Map = null;
this.methodCallIDCount = new AtomicInteger(0);
this.filter = null;
}
查看一下super方法
this.ref
public UnicastRef(LiveRef var1) {
this.ref = var1;
}
new LiveRef方法最终会调用。var1为new ObjID()。var2为TCPEndpoint.getLocalEndpoint(port),类型为TCPEndpoint。var3为true
public LiveRef(ObjID var1, Endpoint var2, boolean var3) {
this.ep = var2;
this.id = var1;
this.isLocal = var3;
}
getLocalEndpoint
查看一下
public static TCPEndpoint getLocalEndpoint(int var0) {
return getLocalEndpoint(var0, (RMIClientSocketFactory)null, (RMIServerSocketFactory)null);
}
public static TCPEndpoint getLocalEndpoint(int var0, RMIClientSocketFactory var1, RMIServerSocketFactory var2) {
TCPEndpoint var3 = null;
synchronized(localEndpoints) {
//只有var0为port,传入有值,其他均为null
TCPEndpoint var5 = new TCPEndpoint((String)null, var0, var1, var2);
//localEndpoints存放的是TCPEndpoint
LinkedList var6 = (LinkedList)localEndpoints.get(var5);
//是否配置了java.rmi.server.hostname
//重新采样主机host
String var7 = resampleLocalHost();
//如果不存在TCPEndpoint,这里重写了equals方法。吐槽一下这个equals方法,垃圾。
if (var6 == null) {
//host,port,null,null
var3 = new TCPEndpoint(var7, var0, var1, var2);
var6 = new LinkedList();
var6.add(var3);
var3.listenPort = var0;
//transport保存自身,这不来个循环引用?
var3.transport = new TCPTransport(var6);
//key为TCPEndpoint,value为TCPTransport
localEndpoints.put(var5, var6);
if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
TCPTransport.tcpLog.log(Log.BRIEF, "created local endpoint for socket factory " + var2 + " on port " + var0);
}
} else {
//如果get到了
synchronized(var6) {
var3 = (TCPEndpoint)var6.getLast();
String var9 = var3.host;
int var10 = var3.port;
TCPTransport var11 = var3.transport;
//如果host变了,就重新创建TCPEndpoint,把这个放到链表的末尾
if (var7 != null && !var7.equals(var9)) {
if (var10 != 0) {
var6.clear();
}
var3 = new TCPEndpoint(var7, var10, var1, var2);
var3.listenPort = var0;
var3.transport = var11;
var6.add(var3);
}
}
}
return var3;
}
}
sun.rmi.transport.tcp.TCPEndpoint构造方法
public TCPEndpoint(String var1, int var2, RMIClientSocketFactory var3, RMIServerSocketFactory var4) {
this.listenPort = -1;
this.transport = null;
if (var1 == null) {
var1 = "";
}
this.host = var1;
this.port = var2;
this.csf = var3;
this.ssf = var4;
}
java.rmi.server.UnicastRemoteObject#exportObject(java.rmi.Remote, sun.rmi.server.UnicastServerRef)
这里是在sref上暴露remoteObject。这个remoteObject就是我们的远程对象。
/**
* Exports the specified object using the specified server ref.
*/
private static Remote exportObject(Remote obj, UnicastServerRef sref)
throws RemoteException
{
// if obj extends UnicastRemoteObject, set its ref.
if (obj instanceof UnicastRemoteObject) {
((UnicastRemoteObject) obj).ref = sref;
}
return sref.exportObject(obj, null, false);
}
sun.rmi.server.UnicastServerRef#exportObject(java.rmi.Remote, java.lang.Object, boolean)
看看如何创建代理对象的。
public Remote exportObject(Remote var1, Object var2, boolean var3) throws RemoteException {
Class var4 = var1.getClass();
Remote var5;
try {
//var5为远程对象的代理对象,Target里装入的也是代理对象
//var4为远程对象的class
//getClientRef返回new UnicastRef(this.ref)
//forceStubUse在构造方法里初始化为false
var5 = Util.createProxy(var4, this.getClientRef(), this.forceStubUse);
} catch (IllegalArgumentException var7) {
throw new ExportException("remote object implements illegal remote interface", var7);
}
//判断var5是否为RemoteStub
if (var5 instanceof RemoteStub) {
this.setSkeleton(var1);
}
//UnicastServerRef对象的this指针,为disp
//动态代理类为stub
//var3为false
Target var6 = new Target(var1, this, var5, this.ref.getObjID(), var3);
//暴露出去代理对象
//调用this.ep.exportObject(var1)。ep就是上面创建的TCPEndPoint
//进入TCPEndPoint,调用this.transport.exportObject(var1)
//创建listen,这里包含socket,以及socket的处理逻辑。exportCount++。
//target设置 setExportedTransport,为this
//ObjectTable存入target。objTable存入getObjectEndpoint->target。implTable存入getWeakImpl->target。
//getObjectEndpoint为new ObjectEndpoint(this.id, this.exportedTransport)。id就是ObjID,this.exportedTransport就是this。
//getWeakImpl返回WeakRef,在构造方法里可以看到,为WeakRef(var1, ObjectTable.reapQueue),var1为remote,就是我们实现的远程对象。
this.ref.exportObject(var6);
//hashToMethod_Maps类型为 WeakClassHashMap<Map<Long, Method>>
//get不到会把var4 put进去。
this.hashToMethod_Map = (Map)hashToMethod_Maps.get(var4);
return var5;
}
sun.rmi.transport.Target#Target
暴露的target类的构造方法
public Target(Remote var1, Dispatcher var2, Remote var3, ObjID var4, boolean var5) {
this.weakImpl = new WeakRef(var1, ObjectTable.reapQueue);
this.disp = var2;
this.stub = var3;
this.id = var4;
this.acc = AccessController.getContext();
ClassLoader var6 = Thread.currentThread().getContextClassLoader();
ClassLoader var7 = var1.getClass().getClassLoader();
//如果var6的祖先加载器有var7
if (checkLoaderAncestry(var6, var7)) {
this.ccl = var6;
} else {
this.ccl = var7;
}
//false,不是永久的
this.permanent = var5;
if (var5) {
this.pinImpl();
}
}
sun.rmi.server.Util#createProxy
public static Remote createProxy(Class<?> var0, RemoteRef var1, boolean var2) throws StubNotFoundException {
Class var3;
try {
//如果var0实现了Remote接口,那么直接返回var0,否则返回实现了Remote接口的超类,否则报错。
var3 = getRemoteClass(var0);
} catch (ClassNotFoundException var9) {
throw new StubNotFoundException("object does not implement a remote interface: " + var0.getName());
}
//var2为false
//ignoreStubClasses在静态块里取值为java.rmi.server.ignoreStubClasses
//withoutStubs类型为Map<Class<?>, Void>,在静态块里取值为Collections.synchronizedMap(new WeakHashMap(11)
//如果withoutStubs不包含var3,那么就尝试加载var3.getName+"_Stub"这个类,加载成功返回true,否则存入withoutStubs,返回false
//withoutStubs包含var3直接返回false
//所以如果是远程对象,不走这条。这里将逻辑杂糅,不太好。
if (var2 || !ignoreStubClasses && stubClassExists(var3)) {
return createStub(var3, var1);
} else {
//远程对象代理。
final ClassLoader var4 = var0.getClassLoader();
//只代理实现了remote的类或接口,要代理的类,这些类的方法都会被代理
final Class[] var5 = getRemoteInterfaces(var0);
//var1为UnicastRef。remote ref
//代理类。继承RemoteObject,实现InvocationHandler
final RemoteObjectInvocationHandler var6 = new RemoteObjectInvocationHandler(var1);
try {
return (Remote)AccessController.doPrivileged(new PrivilegedAction<Remote>() {
public Remote run() {
//动态代理的典型使用
//会调用ref.invoke接口。UnicastRef.invoke方法
return (Remote)Proxy.newProxyInstance(var4, var5, var6);
}
});
} catch (IllegalArgumentException var8) {
throw new StubNotFoundException("unable to create proxy", var8);
}
}
}
sun.rmi.server.UnicastRef#invoke(java.rmi.Remote, java.lang.reflect.Method, java.lang.Object[], long)
//var1为远程对象
//var3为参数
//var4为getMethodHash(method))
public Object invoke(Remote var1, Method var2, Object[] var3, long var4) throws Exception {
if (clientRefLog.isLoggable(Log.VERBOSE)) {
clientRefLog.log(Log.VERBOSE, "method: " + var2);
}
if (clientCallLog.isLoggable(Log.VERBOSE)) {
this.logClientCall(var1, var2);
}
//TCPChannel:this.ep.newSocket()
Connection var6 = this.ref.getChannel().newConnection();
StreamRemoteCall var7 = null;
boolean var8 = true;
boolean var9 = false;
Object var13;
try {
if (clientRefLog.isLoggable(Log.VERBOSE)) {
clientRefLog.log(Log.VERBOSE, "opnum = " + var4);
}
//向var6里输出80
//使用ObjectOutput输出8字节objNum,再输出space,4字节unique,8字节time,2字节count
//再输出4字节-1,8字节getMethodHash(method))
var7 = new StreamRemoteCall(var6, this.ref.getObjID(), -1, var4);
Object var11;
try {
ObjectOutput var10 = var7.getOutputStream();
this.marshalCustomCallData(var10);
//参数类型
var11 = var2.getParameterTypes();
for(int var12 = 0; var12 < ((Object[])var11).length; ++var12) {
//参数类型,参数值,输出流
//向var10里输出序列化的参数
marshalValue((Class)((Object[])var11)[var12], var3[var12], var10);
}
} catch (IOException var39) {
clientRefLog.log(Log.BRIEF, "IOException marshalling arguments: ", var39);
throw new MarshalException("error marshalling arguments", var39);
}
//这个查看一下
var7.executeCall();
try {
Class var46 = var2.getReturnType();
if (var46 == Void.TYPE) {
var11 = null;
return var11;
}
//从输入流里获取返回值
var11 = var7.getInputStream();
Object var47 = unmarshalValue(var46, (ObjectInput)var11);
var9 = true;
clientRefLog.log(Log.BRIEF, "free connection (reuse = true)");
this.ref.getChannel().free(var6, true);
var13 = var47;
} catch (ClassNotFoundException | IOException var40) {
((StreamRemoteCall)var7).discardPendingRefs();
clientRefLog.log(Log.BRIEF, var40.getClass().getName() + " unmarshalling return: ", var40);
throw new UnmarshalException("error unmarshalling return", var40);
} finally {
try {
var7.done();
} catch (IOException var38) {
var8 = false;
}
}
} catch (RuntimeException var42) {
if (var7 == null || ((StreamRemoteCall)var7).getServerException() != var42) {
var8 = false;
}
throw var42;
} catch (RemoteException var43) {
var8 = false;
throw var43;
} catch (Error var44) {
var8 = false;
throw var44;
} finally {
if (!var9) {
if (clientRefLog.isLoggable(Log.BRIEF)) {
clientRefLog.log(Log.BRIEF, "free connection (reuse = " + var8 + ")");
}
this.ref.getChannel().free(var6, var8);
}
}
return var13;
}
sun.rmi.transport.StreamRemoteCall#executeCall
public void executeCall() throws Exception {
DGCAckHandler var2 = null;
byte var1;
try {
if (this.out != null) {
var2 = this.out.getDGCAckHandler();
}
this.releaseOutputStream();
DataInputStream var3 = new DataInputStream(this.conn.getInputStream());
//读1个字节
byte var4 = var3.readByte();
if (var4 != 81) {
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
Transport.transportLog.log(Log.BRIEF, "transport return code invalid: " + var4);
}
throw new UnmarshalException("Transport return code invalid");
}
this.getInputStream();
//再读1个字节
var1 = this.in.readByte();
//读objID
this.in.readID();
} catch (UnmarshalException var11) {
throw var11;
} catch (IOException var12) {
throw new UnmarshalException("Error unmarshaling return header", var12);
} finally {
if (var2 != null) {
var2.release();
}
}
//判断是否有报错
switch (var1) {
case 1:
return;
case 2:
Object var14;
try {
//读一个对象
var14 = this.in.readObject();
} catch (Exception var10) {
this.discardPendingRefs();
throw new UnmarshalException("Error unmarshaling return", var10);
}
if (!(var14 instanceof Exception)) {
this.discardPendingRefs();
throw new UnmarshalException("Return type not Exception");
} else {
this.exceptionReceivedFromServer((Exception)var14);
}
default:
if (Transport.transportLog.isLoggable(Log.BRIEF)) {
Transport.transportLog.log(Log.BRIEF, "return code invalid: " + var1);
}
throw new UnmarshalException("Return code invalid");
}
}
sun.rmi.transport.tcp.TCPTransport#listen
此处起了一个线程用来监听socket,处理远程请求。
private void listen() throws RemoteException {
assert Thread.holdsLock(this);
TCPEndpoint var1 = this.getEndpoint();
int var2 = var1.getPort();
if (this.server == null) {
if (tcpLog.isLoggable(Log.BRIEF)) {
tcpLog.log(Log.BRIEF, "(port " + var2 + ") create server socket");
}
try {
//server的实现是调用 sun.rmi.transport.proxy.RMIMasterSocketFactory,最终创建ServerSocket
this.server = var1.newServerSocket();
//此处用的是多线程阻塞I/O的方式
//AcceptLoop的run方法就是调用sun.rmi.transport.tcp.TCPTransport.AcceptLoop#executeAcceptLoop
Thread var3 = (Thread)AccessController.doPrivileged(new NewThreadAction(new AcceptLoop(this.server), "TCP Accept-" + var2, true));
var3.start();
} catch (BindException var4) {
throw new ExportException("Port already in use: " + var2, var4);
} catch (IOException var5) {
throw new ExportException("Listen failed on port: " + var2, var5);
}
} else {
SecurityManager var6 = System.getSecurityManager();
if (var6 != null) {
var6.checkListen(var2);
}
}
}
sun.rmi.transport.tcp.TCPTransport.AcceptLoop#executeAcceptLoop
注意到使用ExecutorService,查看初始化,注意到
1、如果没有设置sun.rmi.transport.tcp.maxConnectionThreads参数,最大线程数可为Int的最大值。
2、在其中执行的线程有特权。
3、放到ExecutorService里的run方法最后会调用ConnectionHandler.run0。这里是处理远程调用的真正地方。
private void executeAcceptLoop() {
if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
TCPTransport.tcpLog.log(Log.BRIEF, "listening on port " + TCPTransport.this.getEndpoint().getPort());
}
while(true) {
Socket var1 = null;
try {
var1 = this.serverSocket.accept();
InetAddress var16 = var1.getInetAddress();
String var3 = var16 != null ? var16.getHostAddress() : "0.0.0.0";
try {
//var1为建立好连接的socket,var3为ip。
TCPTransport.connectionThreadPool.execute(TCPTransport.this.new ConnectionHandler(var1, var3));
} catch (RejectedExecutionException var11) {
TCPTransport.closeSocket(var1);
TCPTransport.tcpLog.log(Log.BRIEF, "rejected connection from " + var3);
}
} catch (Throwable var15) {
Throwable var2 = var15;
try {
if (this.serverSocket.isClosed()) {
return;
}
try {
if (TCPTransport.tcpLog.isLoggable(Level.WARNING)) {
TCPTransport.tcpLog.log(Level.WARNING, "accept loop for " + this.serverSocket + " throws", var2);
}
} catch (Throwable var13) {
}
} finally {
if (var1 != null) {
TCPTransport.closeSocket(var1);
}
}
if (!(var15 instanceof SecurityException)) {
try {
TCPEndpoint.shedConnectionCaches();
} catch (Throwable var12) {
}
}
if (!(var15 instanceof Exception) && !(var15 instanceof OutOfMemoryError) && !(var15 instanceof NoClassDefFoundError)) {
if (var15 instanceof Error) {
throw (Error)var15;
}
throw new UndeclaredThrowableException(var15);
}
if (!this.continueAfterAcceptFailure(var15)) {
return;
}
}
}
}
UnicastRemoteObject执行逻辑
sun.rmi.transport.tcp.TCPTransport.ConnectionHandler#run0
private void run0() {
TCPEndpoint var1 = TCPTransport.this.getEndpoint();
int var2 = var1.getPort();
TCPTransport.threadConnectionHandler.set(this);
try {
this.socket.setTcpNoDelay(true);
} catch (Exception var31) {
}
try {
if (TCPTransport.connectionReadTimeout > 0) {
this.socket.setSoTimeout(TCPTransport.connectionReadTimeout);
}
} catch (Exception var30) {
}
try {
//获取socket的输入流,返回SocketInputStream
InputStream var3 = this.socket.getInputStream();
//markSupported 判断该输入流能支持mark 和 reset 方法。
Object var4 = var3.markSupported() ? var3 : new BufferedInputStream(var3);
//这里为啥首先缓冲4个字节?
((InputStream) var4).mark(4);
//装饰成DataInputStream
DataInputStream var5 = new DataInputStream((InputStream) var4);
//读4个字节
int var6 = var5.readInt();
//16进制转字符为POST
if (var6 == 1347375956) {
if (TCPTransport.disableIncomingHttp) {
throw new RemoteException("RMI over HTTP is disabled");
}
TCPTransport.tcpLog.log(Log.BRIEF, "decoding HTTP-wrapped call");
((InputStream) var4).reset();
try {
this.socket = new HttpReceiveSocket(this.socket, (InputStream) var4, (OutputStream) null);
this.remoteHost = "0.0.0.0";
var3 = this.socket.getInputStream();
var4 = new BufferedInputStream(var3);
var5 = new DataInputStream((InputStream) var4);
var6 = var5.readInt();
} catch (IOException var29) {
throw new RemoteException("Error HTTP-unwrapping call", var29);
}
}
//读2个字节
short var7 = var5.readShort();
//16进制转字符为JRMP
if (var6 == 1246907721 && var7 == 2) {
OutputStream var8 = this.socket.getOutputStream();
BufferedOutputStream var9 = new BufferedOutputStream(var8);
//var10为输出流
DataOutputStream var10 = new DataOutputStream(var9);
int var11 = this.socket.getPort();
if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
TCPTransport.tcpLog.log(Log.BRIEF, "accepted socket from [" + this.remoteHost + ":" + var11 + "]");
}
//读1个字节
byte var15 = var5.readByte();
TCPEndpoint var12;
TCPChannel var13;
TCPConnection var14;
switch (var15) {
case 75:
//回写78
var10.writeByte(78);
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "(port " + var2 + ") suggesting " + this.remoteHost + ":" + var11);
}
//回写主机host
var10.writeUTF(this.remoteHost);
//回写主机port
var10.writeInt(var11);
//输出
var10.flush();
//readUTF,先读两个字节表示utf的len,然后读取utf_len,然后将byte转int,
String var16 = var5.readUTF();
//读4个字节
int var17 = var5.readInt();
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "(port " + var2 + ") client using " + var16 + ":" + var17);
}
var12 = new TCPEndpoint(this.remoteHost, this.socket.getLocalPort(), var1.getClientSocketFactory(), var1.getServerSocketFactory());
var13 = new TCPChannel(TCPTransport.this, var12);
//var4,var9分别为this.socket的input,output,作为TCPConnection的input、output
var14 = new TCPConnection(var13, this.socket, (InputStream) var4, var9);
//读一个字节,转为int,分别判断80,81,82,83,84,后续对此方法做详细分析
//类名.this一般用于内部类调用外部类的对象时使用
TCPTransport.this.handleMessages(var14, true);
return;
case 76:
//对比75少了回写远程主机信息
var12 = new TCPEndpoint(this.remoteHost, this.socket.getLocalPort(), var1.getClientSocketFactory(), var1.getServerSocketFactory());
var13 = new TCPChannel(TCPTransport.this, var12);
var14 = new TCPConnection(var13, this.socket, (InputStream) var4, var9);
TCPTransport.this.handleMessages(var14, false);
return;
case 77:
//回写主机信息
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "(port " + var2 + ") accepting multiplex protocol");
}
var10.writeByte(78);
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "(port " + var2 + ") suggesting " + this.remoteHost + ":" + var11);
}
var10.writeUTF(this.remoteHost);
var10.writeInt(var11);
var10.flush();
var12 = new TCPEndpoint(var5.readUTF(), var5.readInt(), var1.getClientSocketFactory(), var1.getServerSocketFactory());
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "(port " + var2 + ") client using " + var12.getHost() + ":" + var12.getPort());
}
//这里是新增逻辑,多路复用,单独讲解。
ConnectionMultiplexer var18;
synchronized (TCPTransport.this.channelTable) {
var13 = TCPTransport.this.getChannel(var12);
//var4,var8是input、output作为ConnectionMultiplexer的input、output
var18 = new ConnectionMultiplexer(var13, (InputStream) var4, var8, false);
var13.useMultiplexer(var18);
}
var18.run();
return;
default:
//只写一个79
var10.writeByte(79);
var10.flush();
return;
}
}
TCPTransport.closeSocket(this.socket);
} catch (IOException var32) {
TCPTransport.tcpLog.log(Log.BRIEF, "terminated with exception:", var32);
return;
} finally {
TCPTransport.closeSocket(this.socket);
}
}
sun.rmi.transport.tcp.TCPTransport#handleMessages
void handleMessages(Connection var1, boolean var2) {
int var3 = this.getEndpoint().getPort();
try {
DataInputStream var4 = new DataInputStream(var1.getInputStream());
//do while循环,如果var5不为break中的任意一个,是否可以造成dos攻击。
do {
//读一个字节
int var5 = var4.read();
if (var5 == -1) {
if (tcpLog.isLoggable(Log.BRIEF)) {
tcpLog.log(Log.BRIEF, "(port " + var3 + ") connection closed");
}
break;
}
if (tcpLog.isLoggable(Log.BRIEF)) {
tcpLog.log(Log.BRIEF, "(port " + var3 + ") op = " + var5);
}
//判断
switch (var5) {
case 80:
StreamRemoteCall var6 = new StreamRemoteCall(var1);
if (!this.serviceCall(var6)) {
return;
}
break;
case 81:
case 83:
default:
throw new IOException("unknown transport op " + var5);
case 82:
DataOutputStream var7 = new DataOutputStream(var1.getOutputStream());
var7.writeByte(83);
var1.releaseOutputStream();
break;
case 84:
DGCAckHandler.received(UID.read(var4));
}
} while(var2);
} catch (IOException var17) {
if (tcpLog.isLoggable(Log.BRIEF)) {
tcpLog.log(Log.BRIEF, "(port " + var3 + ") exception: ", var17);
}
} finally {
try {
var1.close();
} catch (IOException var16) {
}
}
}
sun.rmi.transport.Transport#serviceCall
public boolean serviceCall(final RemoteCall var1) {
try {
ObjID var39;
try {
//读8个字节作为num,再读4,8,2个字节new(unique, time, count)作为UID,取名space,然后new ObjID(num, space)
var39 = ObjID.read(var1.getInputStream());
} catch (IOException var33) {
throw new MarshalException("unable to read objID", var33);
}
//dgcID为静态变量,值为ObjID(2, new(0,0,0));
Transport var40 = var39.equals(dgcID) ? null : this;
//getTarget会从objTable取值。objTable为静态变量Hasp<ObjectEndpoint, Target>
//这个Target是远程对象的代理类
Target var5 = ObjectTable.getTarget(new ObjectEndpoint(var39, var40));
final Remote var37;
//var5.getImpl()从Target里的weakRef里取出Remote类,赋值给var37
if (var5 != null && (var37 = var5.getImpl()) != null) {
//从target里取出disp
final Dispatcher var6 = var5.getDispatcher();
//callCount++
var5.incrementCallCount();
boolean var8;
try {
transportLog.log(Log.VERBOSE, "call dispatcher");
//返回acc
final AccessControlContext var7 = var5.getAccessControlContext();
//返回ccl
ClassLoader var41 = var5.getContextClassLoader();
//获得线程上下文加载器
ClassLoader var9 = Thread.currentThread().getContextClassLoader();
try {
setContextClassLoader(var41);
currentTransport.set(this);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws IOException {
Transport.this.checkAcceptPermission(var7);
//在特权模块里执行dispatch,实现类为UnicastServerRef
//var37为var5里的remote
//var1为remotecall
//下面详细展开
var6.dispatch(var37, var1);
return null;
}
}, var7);
return true;
} catch (PrivilegedActionException var31) {
throw (IOException)var31.getException();
}
} finally {
setContextClassLoader(var9);
currentTransport.set((Object)null);
}
} catch (IOException var34) {
transportLog.log(Log.BRIEF, "exception thrown by dispatcher: ", var34);
var8 = false;
} finally {
var5.decrementCallCount();
}
return var8;
}
throw new NoSuchObjectException("no such object in table");
} catch (RemoteException var36) {
RemoteException var2 = var36;
if (UnicastServerRef.callLog.isLoggable(Log.BRIEF)) {
String var3 = "";
try {
var3 = "[" + RemoteServer.getClientHost() + "] ";
} catch (ServerNotActiveException var30) {
}
String var4 = var3 + "exception: ";
UnicastServerRef.callLog.log(Log.BRIEF, var4, var36);
}
try {
ObjectOutput var38 = var1.getResultStream(false);
UnicastServerRef.clearStackTraces(var2);
var38.writeObject(var2);
var1.releaseOutputStream();
} catch (IOException var29) {
transportLog.log(Log.BRIEF, "exception thrown marshalling exception: ", var29);
return false;
}
}
return true;
}
sun.rmi.server.UnicastServerRef#dispatch
public void dispatch(Remote var1, RemoteCall var2) throws IOException {
try {
int var3;
ObjectInput var41;
try {
var41 = var2.getInputStream();
//读1个字节
var3 = var41.readInt();
} catch (Exception var38) {
throw new UnmarshalException("error unmarshalling call header", var38);
}
//调用远程对象,不会走这里
if (this.skel != null) {
this.oldDispatch(var1, var2, var3);
return;
}
if (var3 >= 0) {
throw new UnmarshalException("skeleton class not found but required for client version");
}
long var4;
try {
//读8个字节
var4 = var41.readLong();
} catch (Exception var37) {
throw new UnmarshalException("error unmarshalling call header", var37);
}
//输入流转化。MarshalInputStream
//Provides a MarshalInputStream that uses a caller provided ClassLoader to resolve classes during objects deserialization.
MarshalInputStream var7 = (MarshalInputStream)var41;
var7.skipDefaultResolveClass();
//回头看一下hashToMethod_Map
Method var42 = (Method)this.hashToMethod_Map.get(var4);
if (var42 == null) {
throw new UnmarshalException("unrecognized method hash: method not supported by remote object");
}
this.logCall(var1, var42);
Object[] var9 = null;
try {
//反序列化parameters
this.unmarshalCustomCallData(var41);
var9 = this.unmarshalParameters(var1, var42, var7);
} catch (AccessException var34) {
((StreamRemoteCall)var2).discardPendingRefs();
throw var34;
} catch (ClassNotFoundException | IOException var35) {
((StreamRemoteCall)var2).discardPendingRefs();
throw new UnmarshalException("error unmarshalling arguments", var35);
} finally {
var2.releaseInputStream();
}
Object var10;
try {
//反射调用var1的var42方法,参数为var9。var10为返回值
var10 = var42.invoke(var1, var9);
} catch (InvocationTargetException var33) {
throw var33.getTargetException();
}
try {
ObjectOutput var11 = var2.getResultStream(true);
Class var12 = var42.getReturnType();
if (var12 != Void.TYPE) {
//var12为返回值类型,将var10反序列化后,输出到var11
marshalValue(var12, var10, var11);
}
} catch (IOException var32) {
throw new MarshalException("error marshalling return", var32);
}
} catch (Throwable var39) {
Object var6 = var39;
this.logCallException(var39);
ObjectOutput var8 = var2.getResultStream(false);
if (var39 instanceof Error) {
var6 = new ServerError("Error occurred in server thread", (Error)var39);
} else if (var39 instanceof RemoteException) {
var6 = new ServerException("RemoteException occurred in server thread", (Exception)var39);
}
if (suppressStackTraces) {
clearStackTraces((Throwable)var6);
}
var8.writeObject(var6);
if (var39 instanceof AccessException) {
throw new IOException("Connection is not reusable", var39);
}
} finally {
var2.releaseInputStream();
var2.releaseOutputStream();
}
}
总结
1、远程对象会被包装为一个代理对象,然后再封装为Target,然后发布出去。
2、这个代理对象只代理实现了remote接口的类。
3、发布的意思在TCPEndPoint上开启监听。等待逻辑处理。
直接给远程对象发送消息
import socket
ip_port = ('10.43.234.130', 10999)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
payload = b"%08x" % 1246907721
payload = payload + b"%04x" % 2
payload = payload + b"%02x" % 77
s.connect(ip_port)
s.send(bytes.fromhex(payload.decode('utf-8')))
rcv = s.recv(1024)
a = rcv[0:1]
print(int.from_bytes(rcv[0:1], byteorder="little", signed=False))
# client的host长度
print(int(rcv[1:3].hex(), 16))
# client的host
print(rcv[3:-4].decode("utf-8"))
# client的port
print(int(rcv[-4:].hex(), 16))
返回值