changeset 135:ada4d850a820

lostParent and notFoundParenet
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 07 Jun 2014 19:54:27 +0900
parents 128cce60c43c
children 81b558b38b9f
files src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java
diffstat 8 files changed, 208 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java	Sat Jun 07 19:54:27 2014 +0900
@@ -1,7 +1,6 @@
 package com.glavsoft.rfb.encoding.decoder;
 
 import jp.ac.u_ryukyu.treevnc.MyRfbProto;
-import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient;
 
 import com.glavsoft.drawing.Renderer;
 import com.glavsoft.exceptions.TransportException;
@@ -24,7 +23,9 @@
 			FramebufferUpdateRectangle rect) throws TransportException {
 		int dataLen = getZrleLength(rect, reader);
 		reader.reset();
+		// TreeVNC handling
 		rfb.readSendData(dataLen, reader);
+		// reader is reseted read again
 
 		if (! rfb.isRoot()) {
 		    // decode data when it is a client
--- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Sat Jun 07 19:54:27 2014 +0900
@@ -41,7 +41,6 @@
 import com.glavsoft.rfb.encoding.decoder.ZRLEESender;
 import com.glavsoft.transport.Reader;
 
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.logging.Logger;
@@ -153,14 +152,13 @@
 					System.out.println("task stop");
 					int counter = 0;  // static int ?
 					TreeVncProtocol echo = rfb.getEcho();
-					echo.openport();
 					while(true) {
 						// after set time out. not counter. 
-						if(counter > 3) {
+						if (counter > 3) {
 							echo.notfoundParent();
 						}
 						try {
-                            if(echo.lostHost()) break;
+                            if (echo.lostHost()) break;
                         } catch (Exception e1) {
                             logger.severe("Cannot send lostHost: " + e1.getMessage());
                         }
@@ -223,7 +221,7 @@
 			Decoder decoder = decoders.getDecoderByType(rect.getEncodingType());
 			logger.finest(rect.toString() + (0 == numberOfRectangles ? "\n---" : ""));
 			if (decoder != null) {
-				decoder.decode(reader, renderer, rect);
+				decoder.decode(reader, renderer, rect);  // TreeVNC processing here
 				if(!(rfb.getCuiVersion()))
 					repaintController.repaintBitmap(rect);
 			} else if (rect.getEncodingType() == EncodingType.RICH_CURSOR) {
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java	Sat Jun 07 19:54:27 2014 +0900
@@ -5,8 +5,6 @@
 import java.net.BindException;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.LinkedList;
@@ -39,18 +37,19 @@
 	public MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>();
 	private RequestScreenThread rThread;
 	private boolean proxyFlag = true;
-	public TreeVncProtocol treeProtocol;
 	public int acceptPort = 0;
 	protected boolean readyReconnect = false;
 	private boolean cuiVersion;
 	private long counter = 0; // packet serial number
-	private VncProxyService viewer = null;
+    TreeVncProtocol treeProtocol;
+	public TReeVNCCommand treeVncCommand;
     public ServerSocket servSock;
     private boolean permitChangeScreen = true;
     private static final int INFLATE_BUFSIZE = 1024 * 100;
 
     private Inflater inflater = new Inflater();
     private Deflater deflater = new Deflater();
+    private VncProxyService viewer;
 
 
 	public MyRfbProto() {
@@ -58,7 +57,8 @@
 	}
 	
 	public void setVncProxy(VncProxyService viewer) {
-		this.viewer = viewer;
+	    this.viewer = viewer;
+	    treeVncCommand = new TReeVNCCommand(viewer,this,treeProtocol);
 	}
 
 	abstract public boolean isRoot() ;
@@ -71,7 +71,7 @@
 		sendRfbVersion(os);
 		byte[] b;
 		if ((b = readVersionMsg(is, os))!=null) {
-			treeVncCommand(b,is,os);
+			treeVncCommand.treeVncCommand(b,is,os);
 			return true;
 		}
 		sendSecurityType(os);
@@ -83,86 +83,6 @@
 	}
 	
 	/**
-	 * handle TreeVNC Command
-	 * @param b   12byte header ( command 4byte, length 4byte, port 4byte, option String )
-	 * @param is
-	 * @param os
-	 * @throws TransportException 
-	 * @throws IOException 
-	 */
-	private void treeVncCommand(byte[] b, Reader is, Writer os) throws TransportException, IOException {
-		ByteBuffer buf = ByteBuffer.wrap(b);
-        int command = buf.get()&0xff;
-        buf.position(buf.position()+3);
-        int length = buf.getInt();
-        int port = buf.getInt();
-        String hostname = null;
-        if (length>12) {
-             byte namebuf[] = new byte[length-12];
-             try {
-                is.readBytes(namebuf);
-            } catch (TransportException e) {
-                return;
-            }
-             hostname = new String(namebuf);
-        }
-		switch (command) {
-		case ProtocolContext.FIND_ROOT_REPLY :
-			handleFindRootReply(port,hostname);
-			break;
-        case ProtocolContext.CONNECT_TO_AS_LEADER :
-            handleConnectTo(port,hostname,true);
-            break;
-        case ProtocolContext.CONNECT_TO :
-            handleConnectTo(port,hostname,false);
-            break;
-		case ProtocolContext.FIND_ROOT :
-		    // this is a multicast message, cannot happen
-		    break;
-        case ProtocolContext.WHERE_TO_CONNECT : 
-            handleWhereToConnect(port,hostname);
-		case ProtocolContext.LOST_PARENT :
-			System.out.println("get treeVNC command" + command);
-		}
-	}
-
-	/**
-	 * new clients ask root to where to connect
-	 * tell him his parent
-	 * @param port
-	 * @param hostname
-	 */
-	private void handleWhereToConnect(int port, String hostname) {
-        viewer.replyCreateTree(hostname,port);
-    }
-
-    /**
-	 * set new parent address
-	 * @param port
-	 * @param hostname
-	 * @param leader
-	 * @throws IOException 
-	 * @throws SocketException 
-	 * @throws UnknownHostException 
-	 */
-	private void handleConnectTo(int port, String hostname, boolean leader) throws UnknownHostException, SocketException, IOException {
-        if (isRoot()) {
-            return; // we don't have parent
-        }
-        treeProtocol.connectToParenet(port, hostname,leader);
-    }
-
-    /**
-	 * Accept FIND_ROOT_REPLY
-	 *     add replying TreeVNC root to RootSelection Panel
-	 * @param port
-	 * @param hostname
-	 */
-	private void handleFindRootReply(int port, String hostname) {
-		viewer.addHostToSelectionPanel(port, hostname);
-	}
-
-	/**
 	 * handle new client accept 
 	 *     it also handle TreeVNC Command
 	 * @param acceptThread
@@ -235,9 +155,10 @@
 		};
 		new Thread(timer, "timer-discard-multicastqueue").start();
 		/**
-		 * send all incoming from clients to parent.
+		 * handle command from lower node
 		 */
 		final Runnable reader = new Runnable() {
+
             public void run() {
 				for (;;) {
 					try {
@@ -291,7 +212,7 @@
 
 		};
 		/**
-		 * send packets to a client
+		 * send packets to a client (one thread for each client )
 		 */
 		Runnable sender = new Runnable() {
 			public void run() {
@@ -301,8 +222,7 @@
 
 					// after this, we discard upward packet.
 					new Thread(reader, "upward-packet-processing").start(); 
-					// writeFramebufferUpdateRequest(0,0, framebufferWidth,
-					// framebufferHeight, false );
+
 					for (;;) {
 						LinkedList<ByteBuffer> bufs = c.poll();
 						int inputIndex = 0;
@@ -703,6 +623,13 @@
         return len;
     }
 
+    /**
+     * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet.
+     * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset().
+     * @param dataLen
+     * @param reader
+     * @throws TransportException
+     */
     public void readSendData(int dataLen, Reader reader)
             throws TransportException {
         LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java	Sat Jun 07 19:54:27 2014 +0900
@@ -0,0 +1,138 @@
+package jp.ac.u_ryukyu.treevnc;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.rfb.protocol.ProtocolContext;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+
+import jp.ac.u_ryukyu.treevnc.client.TreeVncProtocol;
+import jp.ac.u_ryukyu.treevnc.server.VncProxyService;
+
+public class TReeVNCCommand {
+    public VncProxyService viewer;
+    MyRfbProto rfb;
+    private TreeVncProtocol treeProtocol;
+
+    public TReeVNCCommand(VncProxyService viewer,MyRfbProto rfb, TreeVncProtocol treeProtocol) {
+        this.viewer = viewer;
+        this.rfb = rfb;
+        this.treeProtocol = treeProtocol;
+    }
+
+    /**
+     * handle TreeVNC Command
+     * @param b   12byte header ( command 4byte, length 4byte, port 4byte, option String )
+     * @param is
+     * @param os
+     * @throws TransportException 
+     * @throws IOException 
+     */
+    void treeVncCommand(byte[] b, Reader is, Writer os) throws TransportException, IOException {
+    	ByteBuffer buf = ByteBuffer.wrap(b);
+        int command = buf.get()&0xff;  // make it unsigned
+        buf.position(buf.position()+3);
+        int length = buf.getInt();
+        int port = buf.getInt();
+        String hostname = null;
+        if (length>12) {
+             byte namebuf[] = new byte[length-12];
+             try {
+                is.readBytes(namebuf);
+            } catch (TransportException e) {
+                return;
+            }
+             hostname = new String(namebuf);
+        }
+    	switch (command) {
+    	case ProtocolContext.FIND_ROOT_REPLY :
+    		handleFindRootReply(port,hostname);
+    		break;
+        case ProtocolContext.CONNECT_TO_AS_LEADER :
+            handleConnectTo( port,hostname,true);
+            break;
+        case ProtocolContext.CONNECT_TO :
+            handleConnectTo( port,hostname,false);
+            break;
+    	case ProtocolContext.FIND_ROOT :
+    	    // this is a multicast message, cannot happen
+    	    break;
+        case ProtocolContext.WHERE_TO_CONNECT : 
+            handleWhereToConnect(port,hostname);
+            break;
+        case ProtocolContext.LOST_PARENT :
+            handleLostParent(port,hostname);
+            break;
+        case ProtocolContext.NOT_FOUND_PARENT :
+            handleNotFoundParent(port,hostname);
+            break;
+    	    default:
+    	        System.out.println("unknown treeVNC command" + command);
+    	}
+    }
+
+
+    /**
+     * new clients ask root to where to connect
+     * tell him his parent
+     * @param port
+     * @param hostname
+     */
+    void handleWhereToConnect(int port, String hostname) {
+        viewer.replyCreateTree(hostname,port);
+    }
+
+    /**
+     * set new parent address
+     * @param port
+     * @param hostname
+     * @param leader
+     * @throws IOException 
+     * @throws SocketException 
+     * @throws UnknownHostException 
+     */
+    void handleConnectTo(int port, String hostname, boolean leader) throws UnknownHostException, SocketException, IOException {
+        if (rfb.isRoot()) {
+            return; // we don't have parent
+        }
+        treeProtocol.connectToParenet(port, hostname,leader);
+    }
+
+    /**
+     * Accept FIND_ROOT_REPLY
+     *     add replying TreeVNC root to RootSelection Panel
+     * @param port
+     * @param hostname
+     */
+    void handleFindRootReply(int port, String hostname) {
+    	viewer.addHostToSelectionPanel(port, hostname);
+    }
+    
+    /**
+     * client node lost parent connection,  send reconnection message.
+     * if root is not here, clients die themselves.
+     * @param port
+     * @param hostname
+     */
+    private void handleLostParent(int port, String hostname) {
+        try {
+            treeProtocol.lostParent(hostname, port);
+        } catch (IOException e) {
+            // log
+        }
+    }
+
+    /**
+     * Some parent is missing. Reorganize tree 
+     * @param port
+     * @param hostname
+     */
+    private void handleNotFoundParent(int port, String hostname) {
+        treeProtocol.notfoundParent(hostname, port);
+    }
+
+}
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java	Sat Jun 07 19:54:27 2014 +0900
@@ -1,14 +1,7 @@
 package jp.ac.u_ryukyu.treevnc.client;
 
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.OutputStream;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
 
 import jp.ac.u_ryukyu.treevnc.MyRfbProto;
 
@@ -46,18 +39,6 @@
 			return false;
 	}
 
-	public byte[] readEchoPort() throws Exception {
-		byte[] b = new byte[4];
-		reader.readBytes(b, 0, b.length);
-		return b;
-	}
-
-
-	@Override
-	public Socket accept() throws IOException {
-		servSock.setReuseAddress(true);
-		return servSock.accept();
-	}
 
 	void sendInitData(OutputStream os) throws IOException {
 		os.write(context.getInitData());
@@ -74,15 +55,6 @@
 		return normalTermination;
 	}
 	
-	@Override
-	public void close() {
-		try {
-			servSock.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-	}
-	
 	/* 
 	 * measure client delay time using tree connection. It should be summed up in upward tree communication 
 	 */
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sat Jun 07 19:54:27 2014 +0900
@@ -4,11 +4,11 @@
 import java.net.*;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+
 import com.glavsoft.rfb.protocol.ProtocolContext;
 import com.glavsoft.viewer.ViewerImpl;
 
 public class TreeVncProtocol {
-	private String proxyName;
 	private BufferedReader is = null;
 	private DataOutputStream os = null;
 	private Socket echoSocket = null;
@@ -24,7 +24,7 @@
 	
 	public TreeVncProtocol(String name, int echoPort) {
 		this.echoPort = echoPort;
-		this.proxyName = name;
+		this.parentAddress = name;
 	}
 
 	public void setLeader(boolean f) {
@@ -33,15 +33,15 @@
 	
 	public void openport() {
 		try {
-			echoSocket = new Socket(proxyName, echoPort);
+			echoSocket = new Socket(parentAddress, echoPort);
 			echoSocket.setReuseAddress(true);
 			os = new DataOutputStream(echoSocket.getOutputStream());
 			is = new BufferedReader(new InputStreamReader(
 					echoSocket.getInputStream()));
 		} catch (UnknownHostException e) {
-			System.err.println("Don't know about host: "+proxyName);
+			System.err.println("Don't know about host: "+parentAddress);
 		} catch (IOException e) {
-			System.out.println(proxyName + " Connection Faild");
+			System.out.println(parentAddress + " Connection Faild");
 			System.exit(0);
 		}
 
@@ -72,18 +72,10 @@
 	    sendCommandToTheRoot(buf);
 	}
 
-    public void sendCommandToTheRoot(ByteBuffer buf) throws IOException {
-        buf.flip();
-
-	    char[] charBuf = new char[12];
-	    is.read(charBuf , 0, 12);                       // skip root's version header
-	    os.write(buf.array(), 0, buf.limit());         // send our command
-	    streamClose();
-    }
-
 	public void lostParent(String hostname, int port) throws IOException {
         sendWithHostAndPort(ProtocolContext.LOST_PARENT, hostname, port);
 	}
+	
 	public void sendWithHostAndPort(int command, String hostname, int port)
 			throws IOException {
 		openport();
@@ -99,7 +91,16 @@
 		buf.put(hostname.getBytes(), 0, hostname.length());
 		sendCommandToTheRoot(buf);
 	}
-	
+
+    public void sendCommandToTheRoot(ByteBuffer buf) throws IOException {
+        buf.flip();
+
+        char[] charBuf = new char[12];
+        is.read(charBuf , 0, 12);                       // skip root's version header
+        os.write(buf.array(), 0, buf.limit());         // send our command
+        streamClose();
+    }
+
 
 	/**
 	 * @param args
@@ -125,9 +126,6 @@
 		}
 		return this;
 	}
-	
-
-	
 
 	/**
 	 * Call at lost host
@@ -155,6 +153,10 @@
 	    return true;
 	}
 
+    public void notfoundParent(String hostname, int port) {
+
+    }
+
     public TreeVncProtocol Interruption(Socket _clientSocket) {
 		clientSocket = _clientSocket;
 		try {
@@ -279,10 +281,13 @@
 		return socket;
 	}
 
-	public String getParentsAddress() {
+	public String getParentAddress() {
 		return parentAddress;
 	}
 
+    public int getParentPort() {
+        return echoPort;
+    }
 	/**
 	 * Start client with new parent (including reconnection) 
 	 * @param port
@@ -301,4 +306,5 @@
         client.run();
     }
 
+
 }
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sat Jun 07 19:54:27 2014 +0900
@@ -15,7 +15,7 @@
 	private boolean addrRegistor = true;
 	boolean runflag = false;
 	private final int treebranch = 2;
-	private String newparent, request, myAddress;
+	private String myAddress;
 	private int leaderflag = 0;
 	private int sendleaderflag = 0;
 	private final int intv_time = 100;
@@ -38,9 +38,9 @@
 					replyLeaderNode(os, is, Integer.parseInt(port), Integer.parseInt(treeNumber));
 				} else if ("2".equals(line)) {
 					// reply to not Found Parents
-					replyNodeInformation(Integer.parseInt(port));
+					TreeVNCNode newparent = replyNodeInformation(Integer.parseInt(port));
 					listupdate(port, newparent);
-					outputStream(os, newparent, String.valueOf(parentnum),
+					outputStream(os, newparent.getHostname(), String.valueOf(parentnum),
 							port, leaderflag==1?"1":"0");
 					os.close();
 					is.close();
@@ -87,9 +87,9 @@
 		nodeList.removeLast();
 	}
 
-	private synchronized void listupdate(String port, String myaddr) {
+	private synchronized void listupdate(String port, TreeVNCNode newparent) {
 		nodeList.remove(Integer.parseInt(port));
-		nodeList.add(Integer.parseInt(port), new TreeVNCNode(myaddr));
+		nodeList.add(Integer.parseInt(port), newparent);
 		nodeList.removeLast();
 	}
 
@@ -132,10 +132,10 @@
 		return addr.getHostAddress();
 	}
 
-	private void replyNodeInformation(int port) {
+	private TreeVNCNode replyNodeInformation(int port) {
 		parentnum = (port - 1) / treebranch;
-		newparent = nodeList.get(parentnum).getHostname();
 		sendleaderflag = decisionLeader(port, treebranch);
+        return  nodeList.get(parentnum);
 	}
 
 	private synchronized void replyLeaderNode(PrintStream os, BufferedReader is, int port, int treeNumber) throws IOException,
@@ -145,7 +145,7 @@
 		if(lastNode != checkSameHost){
 			os.println(lastNode);
 		}
-		replyNodeInformation(port);
+		TreeVNCNode newparent = replyNodeInformation(port);
 		nodeCounter--;
 		reportLastNode(lastNode, newparent, port, parentnum, sendleaderflag);
 		listupdate(port);
@@ -179,7 +179,12 @@
 			}
 		}
 	}
-	
+
+	/**
+	 * Determin tree topology and send CONNECT_TO command
+	 * @param hostname
+	 * @param port
+	 */
 	public void replyCreateTree(String hostname, int port) {
 	    if (addrRegistor == true) {
 	        nodeList.add(new TreeVNCNode(hostname,port));
@@ -192,9 +197,10 @@
 	        if (nodeCounter >= treebranch + 1) {
 	            leaderflag = decisionLeader(nodeCounter, treebranch);
 	            parentnum = (nodeCounter - 1) / treebranch;
-	            request = nodeList.get(parentnum).getHostname();
+	            String request = nodeList.get(parentnum).getHostname();
+	            int port1 = nodeList.get(parentnum).getPort();
 	            checkParameter(parentnum, nodeCounter, leaderflag);
-	            treeProtocol.connectTo(request,port,leaderflag);
+	            treeProtocol.connectTo(request,port1,leaderflag);
 	        } else {
 	            // connect to me
 	            treeProtocol.connectTo(rfb.getMyAddress(),rfb.getAcceptPort(),leaderflag);
@@ -204,14 +210,14 @@
 	    }
 	}
 
-	void reportLastNode(String newchild, String newparent, int newtreenum,
+	void reportLastNode(String newchild, TreeVNCNode newparent, int newtreenum,
 			int newpnum, int newleaderflag) throws IOException {
 		try {
 			System.out.println(newchild + "connect");
 			Socket echoSocket = new Socket(newchild, 10001);
 			DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream());
 			BufferedReader is = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
-			os.writeBytes(newparent + "\n");
+			os.writeBytes(newparent .getHostname() + "\n");
 			os.writeBytes(this.defaultVNCport+"\n");
 			os.writeBytes(newpnum + "\n");
 			// os.writeBytes(newtreenum + "\n");
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java	Sat Jun 07 15:57:03 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java	Sat Jun 07 19:54:27 2014 +0900
@@ -22,4 +22,8 @@
         return hostname;
     }
 
+    public int getPort() {
+        return port;
+    }
+
 }