public void run() {
		while (!sharedData.isEndOfProgram()) {

			long ts = System.currentTimeMillis();
			try {
				selector.select();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			keyIterator = selector.selectedKeys().iterator();
			while (keyIterator.hasNext()) {
				SelectionKey key = keyIterator.next();
				keyIterator.remove();
				if (key.isAcceptable()) {
					SocketChannel socketChannel = null;

					try {
						socketChannel = serverSocketChannel.accept();
					} catch (IOException e) {
						e.printStackTrace();
					}

					if (socketChannel != null) {

						MiddleServer middleServer = new MiddleServer(socketChannel);
						MiddleClient middleClient = new MiddleClient(
								sharedData.getServerIpAddr(),
								sharedData.getServerPortNum());

						middleServer.startServer(null);
						middleClient.startClient();

						middleServer.register(selector, middleClient);

						middleClient.register(selector, middleServer);

						socketMap.put(middleServer.socketChannel, middleServer);
						socketMap.put(middleClient.socketChannel, middleClient);
					}
				} else if (key.isReadable()) {
					while (buffers.isEmpty()) {
					}
					RequestWorker worker = new RequestWorker(sharedData,
							buffers, socketMap.get(key.channel()),
							(MiddleSocketChannel) key.attachment());
					threadPool.execute(worker);
				}
			}

			sharedData.addSelectTime(System.currentTimeMillis() - ts);
		}


		threadPool.shutdown();
		long t0 = sharedData.getSelectTime();
		long t1 = sharedData.getInputTime();
		long t2 = sharedData.getOutputTime();
		long t3 = sharedData.getReturnTime();
		long t = t0 + t1 + t2 + t3;
		System.out.println("t0: " + ((double) t0) / t);
		System.out.println("t1: " + ((double) t1) / t);
		System.out.println("t2: " + ((double) t2) / t);
		System.out.println("t3: " + ((double) t3) / t);

		System.out.println("server socket end");
	}