docs: public void connect (int timeout, InetAddress host, int tcpPort, int udpPort) throws IOException {
  		if (host == null) throw new IllegalArgumentException("host cannot be null.");
  		if (Thread.currentThread() == getUpdateThread())
  			throw new IllegalStateException("Cannot connect on the connection's update thread.");
  		this.connectTimeout = timeout;
  		this.connectHost = host;
  		this.connectTcpPort = tcpPort;
  		this.connectUdpPort = udpPort;
  		close();
  		if (INFO) {
  			if (udpPort != -1)
  				info("kryonet", "Connecting: " + host + ":" + tcpPort + "/" + udpPort);
  			else
  				info("kryonet", "Connecting: " + host + ":" + tcpPort);
  		}
  		id = -1;
  		try {
  			if (udpPort != -1) udp = new UdpConnection(serialization, tcp.readBuffer.capacity());
  
  			long endTime;
  			synchronized (updateLock) {
  				tcpRegistered = false;
  				selector.wakeup();
  				endTime = System.currentTimeMillis() + timeout;
  				tcp.connect(selector, new InetSocketAddress(host, tcpPort), 5000);
  			}
  
  			// Wait for RegisterTCP.
  			synchronized (tcpRegistrationLock) {
  				while (!tcpRegistered && System.currentTimeMillis() < endTime) {
  					try {
  						tcpRegistrationLock.wait(100);
  					} catch (InterruptedException ignored) {
  					}
  				}
  				if (!tcpRegistered) {
  					throw new SocketTimeoutException("Connected, but timed out during TCP registration.\n"
  						+ "Note: Client#update must be called in a separate thread during connect.");
  				}
  			}
  
  			if (udpPort != -1) {
  				InetSocketAddress udpAddress = new InetSocketAddress(host, udpPort);
  				synchronized (updateLock) {
  					udpRegistered = false;
  					selector.wakeup();
  					udp.connect(selector, udpAddress);
  				}
  
  				// Wait for RegisterUDP reply.
  				synchronized (udpRegistrationLock) {
  					while (!udpRegistered && System.currentTimeMillis() < endTime) {
  						RegisterUDP registerUDP = new RegisterUDP();
  						registerUDP.connectionID = id;
  						udp.send(this, registerUDP, udpAddress);
  						try {
  							udpRegistrationLock.wait(100);
  						} catch (InterruptedException ignored) {
  						}
  					}
  					if (!udpRegistered)
  						throw new SocketTimeoutException("Connected, but timed out during UDP registration: " + host + ":" + udpPort);
  				}
  			}
  		} catch (IOException ex) {
  			close();
  			throw ex;
  		}
  	}