| 1 | /*
|
|---|
| 2 | Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
|
|---|
| 3 |
|
|---|
| 4 | This file is part of GNU Classpath.
|
|---|
| 5 |
|
|---|
| 6 | GNU Classpath is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 2, or (at your option)
|
|---|
| 9 | any later version.
|
|---|
| 10 |
|
|---|
| 11 | GNU Classpath is distributed in the hope that it will be useful, but
|
|---|
| 12 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|---|
| 14 | General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with GNU Classpath; see the file COPYING. If not, write to the
|
|---|
| 18 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|---|
| 19 | 02111-1307 USA.
|
|---|
| 20 |
|
|---|
| 21 | Linking this library statically or dynamically with other modules is
|
|---|
| 22 | making a combined work based on this library. Thus, the terms and
|
|---|
| 23 | conditions of the GNU General Public License cover the whole
|
|---|
| 24 | combination.
|
|---|
| 25 |
|
|---|
| 26 | As a special exception, the copyright holders of this library give you
|
|---|
| 27 | permission to link this library with independent modules to produce an
|
|---|
| 28 | executable, regardless of the license terms of these independent
|
|---|
| 29 | modules, and to copy and distribute the resulting executable under
|
|---|
| 30 | terms of your choice, provided that you also meet, for each linked
|
|---|
| 31 | independent module, the terms and conditions of the license of that
|
|---|
| 32 | module. An independent module is a module which is not derived from
|
|---|
| 33 | or based on this library. If you modify this library, you may extend
|
|---|
| 34 | this exception to your version of the library, but you are not
|
|---|
| 35 | obligated to do so. If you do not wish to do so, delete this
|
|---|
| 36 | exception statement from your version. */
|
|---|
| 37 |
|
|---|
| 38 | package gnu.java.rmi.server;
|
|---|
| 39 |
|
|---|
| 40 | import java.lang.Runnable;
|
|---|
| 41 | import java.net.Socket;
|
|---|
| 42 | import java.net.ServerSocket;
|
|---|
| 43 | import java.io.DataInputStream;
|
|---|
| 44 | import java.io.DataOutputStream;
|
|---|
| 45 | import java.io.ObjectInputStream;
|
|---|
| 46 | import java.io.ObjectOutputStream;
|
|---|
| 47 | import java.io.BufferedInputStream;
|
|---|
| 48 | import java.io.BufferedOutputStream;
|
|---|
| 49 | import java.io.ObjectOutput;
|
|---|
| 50 | import java.io.ObjectInput;
|
|---|
| 51 | import java.io.IOException;
|
|---|
| 52 | import java.rmi.RemoteException;
|
|---|
| 53 |
|
|---|
| 54 | public class UnicastConnection
|
|---|
| 55 | implements Runnable, ProtocolConstants {
|
|---|
| 56 |
|
|---|
| 57 | UnicastConnectionManager manager;
|
|---|
| 58 | Socket sock;
|
|---|
| 59 | DataInputStream din;
|
|---|
| 60 | DataOutputStream dout;
|
|---|
| 61 | ObjectInputStream oin;
|
|---|
| 62 | ObjectOutputStream oout;
|
|---|
| 63 |
|
|---|
| 64 | // reviveTime and expireTime make UnicastConnection pool-able
|
|---|
| 65 | long reviveTime = 0;
|
|---|
| 66 | long expireTime = Long.MAX_VALUE;
|
|---|
| 67 |
|
|---|
| 68 | UnicastConnection(UnicastConnectionManager man, Socket sock) {
|
|---|
| 69 | this.manager = man;
|
|---|
| 70 | this.sock = sock;
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | void acceptConnection() throws IOException {
|
|---|
| 74 | //System.out.println("Accepting connection on " + sock);
|
|---|
| 75 | //Use BufferedXXXStream would be more efficient
|
|---|
| 76 | din = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
|
|---|
| 77 | dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
|
|---|
| 78 |
|
|---|
| 79 | int sig = din.readInt();
|
|---|
| 80 | if (sig != PROTOCOL_HEADER) {
|
|---|
| 81 | throw new IOException("bad protocol header");
|
|---|
| 82 | }
|
|---|
| 83 | short ver = din.readShort();
|
|---|
| 84 | if (ver != PROTOCOL_VERSION) {
|
|---|
| 85 | throw new IOException("bad protocol version");
|
|---|
| 86 | }
|
|---|
| 87 | int protocol = din.readUnsignedByte();
|
|---|
| 88 | if (protocol != SINGLE_OP_PROTOCOL) {
|
|---|
| 89 | // Send an ACK
|
|---|
| 90 | dout.writeByte(PROTOCOL_ACK);
|
|---|
| 91 |
|
|---|
| 92 | // Send my hostname and port
|
|---|
| 93 | dout.writeUTF(manager.serverName);
|
|---|
| 94 | dout.writeInt(manager.serverPort);
|
|---|
| 95 | dout.flush();
|
|---|
| 96 |
|
|---|
| 97 | // Read their hostname and port
|
|---|
| 98 | String rhost = din.readUTF();
|
|---|
| 99 | int rport = din.readInt();
|
|---|
| 100 | }
|
|---|
| 101 | // Okay, ready to roll ...
|
|---|
| 102 | }
|
|---|
| 103 |
|
|---|
| 104 | void makeConnection(int protocol) throws IOException {
|
|---|
| 105 | //Use BufferedXXXStream would be more efficient
|
|---|
| 106 | din = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
|
|---|
| 107 | dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
|
|---|
| 108 |
|
|---|
| 109 | // Send header
|
|---|
| 110 | dout.writeInt(PROTOCOL_HEADER);
|
|---|
| 111 | dout.writeShort(PROTOCOL_VERSION);
|
|---|
| 112 | dout.writeByte(protocol);
|
|---|
| 113 | dout.flush();
|
|---|
| 114 |
|
|---|
| 115 | if (protocol != SINGLE_OP_PROTOCOL) {
|
|---|
| 116 | // Get back ack.
|
|---|
| 117 | int ack = din.readUnsignedByte();
|
|---|
| 118 | if (ack != PROTOCOL_ACK) {
|
|---|
| 119 | throw new RemoteException("Unsupported protocol");
|
|---|
| 120 | }
|
|---|
| 121 |
|
|---|
| 122 | // Read in host and port
|
|---|
| 123 | String dicard_rhost = din.readUTF();
|
|---|
| 124 | int discard_rport = din.readInt();
|
|---|
| 125 |
|
|---|
| 126 | // Send them my endpoint
|
|---|
| 127 | dout.writeUTF(manager.serverName);
|
|---|
| 128 | dout.writeInt(manager.serverPort);
|
|---|
| 129 | dout.flush();
|
|---|
| 130 | }
|
|---|
| 131 | // Okay, ready to roll ...
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | DataInputStream getDataInputStream() throws IOException {
|
|---|
| 135 | return (din);
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 | DataOutputStream getDataOutputStream() throws IOException {
|
|---|
| 139 | return (dout);
|
|---|
| 140 | }
|
|---|
| 141 |
|
|---|
| 142 | ObjectInputStream getObjectInputStream() throws IOException {
|
|---|
| 143 | if (oin == null) {
|
|---|
| 144 | oin = new RMIObjectInputStream(din);
|
|---|
| 145 | }
|
|---|
| 146 | return (oin);
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 | ObjectOutputStream getObjectOutputStream() throws IOException {
|
|---|
| 150 | if (oout == null) {
|
|---|
| 151 | oout = new RMIObjectOutputStream(dout);
|
|---|
| 152 | }
|
|---|
| 153 | return (oout);
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | void disconnect() {
|
|---|
| 157 | try {
|
|---|
| 158 | if(oout != null)
|
|---|
| 159 | oout.close();
|
|---|
| 160 | sock.close();
|
|---|
| 161 | }
|
|---|
| 162 | catch (IOException _) {
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | oin = null;
|
|---|
| 166 | oout = null;
|
|---|
| 167 | din = null;
|
|---|
| 168 | dout = null;
|
|---|
| 169 | sock = null;
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | public static final long CONNECTION_TIMEOUT = 10000L;
|
|---|
| 173 |
|
|---|
| 174 | static boolean isExpired(UnicastConnection conn, long l){
|
|---|
| 175 | if (l <= conn.expireTime )
|
|---|
| 176 | return false;
|
|---|
| 177 | return true;
|
|---|
| 178 | }
|
|---|
| 179 |
|
|---|
| 180 | static void resetTime(UnicastConnection conn){
|
|---|
| 181 | long l = System.currentTimeMillis();
|
|---|
| 182 | conn.reviveTime = l;
|
|---|
| 183 | conn.expireTime = l + CONNECTION_TIMEOUT;
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | /**
|
|---|
| 187 | * We run connects on the server. Dispatch it then discard it.
|
|---|
| 188 | */
|
|---|
| 189 | public void run() {
|
|---|
| 190 | do{
|
|---|
| 191 | try {
|
|---|
| 192 | UnicastServer.dispatch(this);
|
|---|
| 193 | //don't discardConnection explicitly, only when
|
|---|
| 194 | // exception happens or the connection's expireTime
|
|---|
| 195 | // comes
|
|---|
| 196 | } catch (Exception e ){
|
|---|
| 197 | manager.discardConnection(this);
|
|---|
| 198 | break;
|
|---|
| 199 | }
|
|---|
| 200 | }while(true);
|
|---|
| 201 | }
|
|---|
| 202 |
|
|---|
| 203 | }
|
|---|