package elte.java2_utikalauz5.rmi; import java.io.*; import java.nio.channels.*; import java.net.*; import java.rmi.*; import java.rmi.registry.*; import java.rmi.server.*; /** Névjegyzékkészítő inetd eléréshez. @link.forrásfájl {@docRoot}/../data/rmi/src InetdSzerver.java @since Java 2 Útikalauz programozóknak 5.0 */ class RegistryKeszito { private static final Object zár = new Object(); private static boolean elérhető = false, vanMár = false; private void InitializeRegistry() { throw new AssertionError();// ne lehessen példányosítani } public static void init(Remote proxy,String név,int port) throws IOException{ synchronized (RegistryKeszito.class) {// csak egyszer hívható if (vanMár) throw new IllegalStateException("már van belőle"); vanMár = true; } Channel csatorna = System.inheritedChannel(); ServerSocket ss = null; if (csatorna instanceof ServerSocketChannel) ss = ((ServerSocketChannel) csatorna).socket();// inetd hívás else if (csatorna == null) {// kézi indítás if (port==0) throw new IllegalArgumentException("érvénytelen port"); ss = new ServerSocket(port); } else throw new IOException("érvénytelen átvett csatorna: " + csatorna); RMIServerSocketFactory ssf = new InetdVegpontgenerator(ss); Registry registry = LocateRegistry.createRegistry(port, null, ssf); try { registry.bind(név, proxy); } catch (RemoteException imposs){ throw new AssertionError(imposs); } catch (AlreadyBoundException impos){throw new AssertionError(impos);} synchronized (zár) {// innentől lehet fogadni elérhető = true; zár.notifyAll(); } } /** Az inetd-kapcsolatot megvalósító végpontgenerátor. @link.forrásfájl {@docRoot}/../data/rmi/src InetdSzerver.java @since Java 2 Útikalauz programozóknak 5.0 */ private static class InetdVegpontgenerator implements RMIServerSocketFactory { private final ServerSocket ss; InetdVegpontgenerator(ServerSocket serverSocket) {ss = serverSocket;} public ServerSocket createServerSocket(int port) throws IOException { return new InetdVegpont(ss); } } // ez a fajta végpont csak akkortól él, amikor már bejegyeztük // a szolgáltatást a registrybe (elérhető jelzi a RegistryKészítőben) /** Inetd-kapcsolatoti végpont. @link.forrásfájl {@docRoot}/../data/rmi/src InetdSzerver.java @since Java 2 Útikalauz programozóknak 5.0 */ private static class InetdVegpont extends ServerSocket { private final ServerSocket ss; InetdVegpont(ServerSocket serverSocket) throws IOException { ss = serverSocket; }// ez végzi a késleltetést (amíg bejegyezzük a szolgáltatást) public Socket accept() throws IOException { synchronized (zár) { try { while (!elérhető) zár.wait(); } catch (InterruptedException e) { throw (IOException)(new InterruptedIOException()).initCause(e); } } return ss.accept(); }// a végpont szokványos működését végző metódusok public InetAddress getInetAddress() {return ss.getInetAddress();} public ServerSocketChannel getChannel() {return ss.getChannel();} public int getLocalPort() { return ss.getLocalPort(); } public void close() throws IOException { ss.close(); } public boolean isBound() { return ss.isBound(); } public boolean isClosed() { return ss.isClosed(); } public String toString() { return ss.toString(); } public void setSoTimeout(int időkorlát) throws SocketException { ss.setSoTimeout(időkorlát); } public int getSoTimeout() throws IOException {return ss.getSoTimeout();} public void setReuseAddress(boolean újra) throws SocketException { ss.setReuseAddress(újra); } public void bind(SocketAddress végpont) throws IOException{ss.bind(végpont);} public void bind(SocketAddress végpont, int napló) throws IOException { ss.bind(végpont, napló); } public SocketAddress getLocalSocketAddress() { return ss.getLocalSocketAddress(); } public boolean getReuseAddress() throws SocketException { return ss.getReuseAddress(); } public void setReceiveBufferSize(int méret) throws SocketException { ss.setReceiveBufferSize(méret); } public int getReceiveBufferSize() throws SocketException { return ss.getReceiveBufferSize(); } } } /** Inetd-s napszak szerver. Használatához megfelelően konfigurálni kell az {@code inetd} folyamatindítót! @link.forrásfájl {@docRoot}/../data/rmi/src InetdSzerver.java @link.letöltés {@docRoot}/../data/rmi InetdSzerver.jar @since Java 2 Útikalauz programozóknak 5.0 */ public class InetdSzerver implements InetdInterfesz { public InetdSzerver() {} public boolean délelőttVan() { return ( (new java.util.GregorianCalendar()).get(java.util.Calendar.AM_PM) ) == java.util.Calendar.AM; } public static void main(String[] paraméter) { hibanaplótKészít(); int port = 0; if (paraméter.length > 0) try { port = Integer.parseInt(paraméter[0]); } catch (NumberFormatException e) {kilépNaplózva("érvénytelen port",e);} InetdInterfesz szervercsonk = new InetdSzerver(); Remote proxy = null; try {// dinamikus proxyt használunk proxy = UnicastRemoteObject.exportObject(szervercsonk, 0); } catch (RemoteException e) { kilépNaplózva("hiba a távoli szolgáltatás létrehozása során", e); } try { RegistryKeszito.init(proxy, "InetdInterfész", port); } catch(IllegalArgumentException e){kilépNaplózva("érvénytelen port",e); } catch (Exception e) {kilépNaplózva("hiba történt", e);} System.err.println("a távoli szolgáltatás készen áll"); try {// várakozás kapcsolatra Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { throw new AssertionError(e); } }// System.err átirányítása file-ba private static void hibanaplótKészít() { try { File fájl = File.createTempFile("szerver-hibanaplo", null, null); System.setErr(new PrintStream(new FileOutputStream(fájl))); } catch (IOException e) { kilépNaplózva("hiba merült fel a hibanapló létrehozása során", e); } } private static void kilépNaplózva(String üzenet, Exception e) { System.err.println("Szerveroldali üzenet: " + üzenet + ": "); e.printStackTrace(); System.exit(1); } }