use of com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream in project CommandHelper by EngineHub.
the class PNViewer method startServer.
public static void startServer(int port, final String password) throws IOException {
ServerSocket socket = new ServerSocket(port);
log("Server started on port " + port + ". Type Ctrl+C to kill the server.");
log("Process info: " + ManagementFactory.getRuntimeMXBean().getName());
log("Server version: " + PROTOCOL_VERSION);
connection: while (true) {
log("Persistence Network Viewers may now connect to this server.");
final Socket s = socket.accept();
log("A client has connected from " + s.getInetAddress().toString());
new Thread(new Runnable() {
@Override
public void run() {
Thread waitThread = null;
try {
final AtomicBoolean dataReceieved = new AtomicBoolean(false);
final AtomicBoolean longTimeout = new AtomicBoolean(false);
waitThread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
synchronized (dataReceieved) {
dataReceieved.wait(longTimeout.get() ? 10 * 60 * 1000 : 10 * 1000);
}
if (dataReceieved.get() == false) {
log("No response from client in too long, forcibly closing connection.");
try {
s.close();
} catch (IOException ex) {
//
}
break;
}
dataReceieved.set(false);
}
} catch (InterruptedException ex) {
//
}
}
});
waitThread.start();
ObjectInputStream is = new ObjectInputStream(s.getInputStream());
ObjectOutputStream os = new AutoFlushObjectOutputStream(s.getOutputStream());
int protocolVersion = is.readInt();
if (protocolVersion != PROTOCOL_VERSION) {
log("Client version unsupported: " + protocolVersion);
os.writeUTF("VERSION-MISMATCH");
return;
} else {
log("Client version supported: " + protocolVersion);
os.writeUTF("VERSION-OK");
}
String clientPassword = is.readUTF();
if (!password.equals(clientPassword)) {
log("Client supplied the wrong password, disconnecting.");
os.writeUTF("PASSWORD-BAD");
os.writeUTF("DISCONNECT");
return;
} else {
if (!"".equals(password)) {
log("Client supplied the correct password");
}
os.writeUTF("PASSWORD-OK");
}
// They have now authed correctly, so we can up the idle time.
longTimeout.set(true);
// Now we need to create instance variables for the remainder of
// the connection, that is, the meat of the connection.
String remoteFile = null;
PersistenceNetwork pn = null;
connected: while (s.isConnected()) {
String command = is.readUTF();
log("Command received from client: " + command);
dataReceieved.set(true);
synchronized (dataReceieved) {
dataReceieved.notifyAll();
}
switch(command) {
case "DISCONNECT":
// Write the disconnect out to the client as well, so
// the client will gracefully disconnect.
os.writeUTF("DISCONNECT");
break connected;
case "SET-REMOTE-FILE":
remoteFile = is.readUTF();
log("File set to " + remoteFile);
if (new File(remoteFile).exists()) {
log("File accepted.");
os.writeUTF("FILE-OK");
} else {
log("File not accepted.");
os.writeUTF("FILE-BAD");
os.writeUTF("DISCONNECT");
}
break;
case "LOAD-DATA":
os.writeUTF("LOAD-DATA");
try {
// Load the data from the PN, and send it on
pn = getPersistenceNetwork(remoteFile);
Map<String[], String> data = pn.getNamespace(ArrayUtils.EMPTY_STRING_ARRAY);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data);
oos.flush();
byte[] output = baos.toByteArray();
os.writeInt(output.length);
os.write(output);
} catch (URISyntaxException | DataSourceException ex) {
os.writeUTF("LOAD-ERROR");
os.writeUTF(ex.getMessage());
log("Load error!");
log(ex);
}
break;
case "KEY-SOURCE":
os.writeUTF("KEY-SOURCE");
String key = is.readUTF();
if (pn == null) {
log("pn is null, can't get key source");
os.writeUTF("DISCONNECT");
} else {
log("Requested source for key: " + key);
URI uri = pn.getKeySource(key.split("\\."));
log("Responding with: " + uri);
os.writeObject(uri);
}
break;
default:
// Bad command, disconnect them.
os.writeUTF("DISCONNECT");
break connected;
}
}
} catch (IOException ex) {
// Disconnected
} finally {
try {
s.close();
} catch (IOException ex) {
//
}
log("Client has disconnected.");
if (waitThread != null) {
waitThread.interrupt();
}
}
}
}).start();
}
}
use of com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream in project CommandHelper by EngineHub.
the class PNViewer method loadFromRemote.
private void loadFromRemote(final String host, final int port, final String password, final String remoteFile) {
remoteSocketThread = new Thread(new Runnable() {
@Override
public void run() {
try {
try (Socket s = new Socket()) {
s.connect(new InetSocketAddress(host, port), 30000);
remoteSocket = s;
setStatus("Connected to remote server", true);
setProgress(null);
try {
final ObjectOutputStream os = new AutoFlushObjectOutputStream(s.getOutputStream());
final ObjectInputStream is = new ObjectInputStream(s.getInputStream());
remoteOutput = os;
remoteInput = is;
// Set up our initial data
log("Writing client version: " + PROTOCOL_VERSION);
os.writeInt(PROTOCOL_VERSION);
switch(is.readUTF()) {
case "VERSION-OK":
break;
default:
showError("The server does not support this client's version.");
return;
}
os.writeUTF(password);
switch(is.readUTF()) {
case "PASSWORD-OK":
log("Password accepted by server.");
break;
default:
showError("Server rejected our password. Check the password and try again.");
return;
}
os.writeUTF("SET-REMOTE-FILE");
os.writeUTF(remoteFile);
final MutableObject<Map<String[], String>> data = new MutableObject<>();
final MutableObject<URI> sourceURI = new MutableObject<>();
VirtualPersistenceNetwork vpn = null;
connection: while (!Thread.currentThread().isInterrupted() && s.isConnected()) {
String serverCommand = is.readUTF();
switch(serverCommand) {
case "DISCONNECT":
break connection;
case "FILE-OK":
os.writeUTF("LOAD-DATA");
reloadButton.setEnabled(false);
break;
case "FILE-BAD":
showError("Remote file doesn't exist, disconnecting.");
break;
case "LOAD-DATA":
int size = is.readInt();
setStatus("Downloading data from server...", true);
setProgress(0);
byte[] bdata = new byte[size];
for (int i = 0; i < size; i++) {
bdata[i] = is.readByte();
setProgress((int) ((((double) i) / ((double) size)) * 100));
}
setStatus("Processing data from server", true);
setProgress(null);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bdata));
try {
Map<String[], String> d = (Map<String[], String>) ois.readObject();
data.setObject(d);
vpn = new VirtualPersistenceNetwork() {
Map<String, URI> sources = new HashMap<>();
@Override
public Map<String[], String> getAllData() throws DataSourceException {
return data.getObject();
}
@Override
public URI getKeySource(String[] key) {
String kk = join(key);
if (!sources.containsKey(kk)) {
try {
sourceURI.setObject(null);
os.writeUTF("KEY-SOURCE");
os.writeUTF(kk);
synchronized (sourceURI) {
if (sourceURI.getObject() == null) {
try {
sourceURI.wait();
} catch (InterruptedException ex) {
//
}
}
}
URI uri = sourceURI.getObject();
sources.put(kk, uri);
} catch (IOException ex) {
showError(ex.getMessage());
log(ex);
}
}
return sources.get(kk);
}
};
try {
displayData(vpn);
setStatus("Done.", false);
} catch (DataSourceException ex) {
log(ex);
showError(ex.getMessage());
}
} catch (ClassNotFoundException ex) {
log(ex);
showError(ex.getMessage());
}
reloadButton.setEnabled(true);
break;
case "KEY-SOURCE":
try {
URI uri = (URI) is.readObject();
sourceURI.setObject(uri);
synchronized (sourceURI) {
sourceURI.notifyAll();
}
} catch (ClassNotFoundException ex) {
log(ex);
}
break;
case "LOAD-ERROR":
String message = is.readUTF();
setStatus(message, false);
showError(message);
reloadButton.setEnabled(true);
break;
default:
showError("Server sent unrecognized command, disconnecting.");
log("Unrecognized command: " + serverCommand);
break connection;
}
}
log("Closing connection.");
} catch (EOFException ex) {
log(ex);
showError("The server closed the connection unexpectedly.");
}
} catch (SocketTimeoutException ex) {
showError("Connection timed out, check your settings and try again.");
} finally {
setStatus("Connection to remote server closed.", false);
remoteOutput = null;
remoteInput = null;
reloadButton.setEnabled(true);
}
} catch (IOException ex) {
showError(ex.getMessage());
Logger.getLogger(PNViewer.class.getName()).log(Level.SEVERE, null, ex);
}
remoteSocketThread = null;
}
});
remoteSocketThread.start();
}
Aggregations