23 package com.realtime.crossfire.jxclient.server.socket;
28 import java.io.EOFException;
29 import java.io.IOException;
30 import java.net.InetSocketAddress;
31 import java.net.SocketAddress;
32 import java.net.SocketException;
33 import java.nio.Buffer;
34 import java.nio.BufferOverflowException;
35 import java.nio.ByteBuffer;
36 import java.nio.ByteOrder;
37 import java.nio.channels.SelectableChannel;
38 import java.nio.channels.SelectionKey;
39 import java.nio.channels.Selector;
40 import java.nio.channels.SocketChannel;
41 import java.nio.channels.UnresolvedAddressException;
42 import java.util.Collection;
43 import org.jetbrains.annotations.NotNull;
44 import org.jetbrains.annotations.Nullable;
197 private final Thread
thread =
new Thread(this::process,
"JXClient:ClientSocket");
226 public void stop() throws InterruptedException {
233 }
catch (
final IOException ex) {
270 if (this.host ==
null || this.port == 0 || !this.host.equals(
host) || this.port !=
port) {
286 public void disconnect(@NotNull
final String reason,
final boolean isError) {
307 while (!
thread.isInterrupted()) {
313 }
catch (
final EOFException ex) {
314 final String tmp = ex.getMessage();
315 final String message = tmp ==
null ?
"EOF" : tmp;
320 }
catch (
final IOException ex) {
321 final String tmp = ex.getMessage();
322 final String message = tmp ==
null ?
"I/O error" : tmp;
336 final boolean notifyConnected;
339 notifyConnected =
false;
345 notifyConnected =
true;
347 notifyConnected =
false;
351 if (notifyConnected) {
353 clientSocketListener.connected();
363 assert Thread.currentThread() ==
thread;
366 final boolean doDisconnect;
367 @Nullable
final String disconnectReason;
368 final boolean disconnectIsError;
374 doDisconnect =
false;
375 disconnectReason =
"reconnect to "+
host+
":"+
port;
376 disconnectIsError =
false;
385 doDisconnect =
false;
386 disconnectReason =
null;
387 disconnectIsError =
false;
391 assert disconnectReason !=
null;
393 final String connectHost;
394 final int connectPort;
400 if (connectHost !=
null) {
415 if (Thread.currentThread().isInterrupted()) {
418 final Collection<SelectionKey> selectedKeys =
selector.selectedKeys();
427 assert selectedKeys.isEmpty();
437 assert Thread.currentThread() ==
thread;
443 clientSocketListener.connecting();
446 final SocketAddress socketAddress =
new InetSocketAddress(
host,
port);
456 }
catch (
final UnresolvedAddressException ex) {
457 throw new IOException(
"Cannot resolve address: "+socketAddress, ex);
458 }
catch (
final IllegalArgumentException ex) {
459 throw new IOException(ex.getMessage(), ex);
463 }
catch (
final SocketException ex) {
487 assert Thread.currentThread() ==
thread;
492 final boolean notifyListeners;
497 if (notifyListeners) {
512 }
catch (
final IOException ignored) {
519 }
catch (
final IOException ignored) {
528 if (notifyListeners) {
531 clientSocketListener.disconnected(reason);
548 throw new EOFException(
"EOF");
578 packet.order(ByteOrder.BIG_ENDIAN);
581 clientSocketListener.packetReceived(packet);
610 }
catch (
final BufferOverflowException ex) {
611 throw new IOException(
"buffer overflow", ex);
613 }
catch (
final IOException ignored) {
616 }
catch (
final IOException ignore) {
625 clientSocketListener.packetSent(monitor);
659 final int newInterestOps;
662 newInterestOps =
interestOps|SelectionKey.OP_WRITE;
664 newInterestOps =
interestOps&~SelectionKey.OP_WRITE;