Anyway, basically, the following code is a Thread that will read from client sockets and terminate the connection after reading once. It's mainly here so you could pick up on a few key elements from reading sockets. I'll go over them in another post, maybe.
package org.neglected.pingserver;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
/**
* This class handles the response of a ping to a client.<br/>
* A new instance of this class (and thus, a new thread) will be created<br/>
* every time a connection is established.<br/>
* <br/>
* The thread will then send a message back to the client giving the time it took to ping this location.
* @author Neglected
*
*/
public final class ResponseThread implements Runnable {
private final Socket pClient;
/**
* Assign our client to the variable pClient.<br />
* We don't need to start this thread, since the Executor does that for us.
* @param pClient - the connected client.
*/
public ResponseThread(Socket pClient) {
this.pClient = pClient;
}
@SuppressWarnings("finally")
@Override
public void run() {
// Try and open the input and output streams.
DataInputStream in = null;
DataOutputStream out = null;
try {
in = new DataInputStream(new BufferedInputStream(pClient.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(pClient.getOutputStream()));
} catch (IOException e) {
// If we can't open the streams, error and try closing the client.
PingServer.println("Could not establish input and output streams for "+pClient.getLocalAddress().getCanonicalHostName()+".", true);
try {
pClient.close();
// If we can't close the client, ignore the exception, since the client must be closed already.
} catch (Exception a) {}
}
// Make a loop to infinitely wait for input.
while(true) {
try {
byte[] buff = new byte[12]; // Create our buffer for the data.
in.read(buff); // Put all the data we receive into the buffer.
ByteBuffer buffer = ByteBuffer.wrap(buff);
// Now we have all of our data stored in buffer.
// Now we need to read it from this buffer.
// Our packet structure is such that we have the following the only packet we send:
// int opcode; -- Occupies 4 bytes.
// long sendTime; -- Occupies 8 bytes.
// Therefore, we just need to read those bytes.
@SuppressWarnings("unused")
int opcode = buffer.getInt(); // We can ignore this in this example, but for applications with more than one operation,
// we can use the opcode system as a way of determining which action to run.
long sendTime = buffer.getLong();
// Now we have the data! We just need to return the packet now.
long diff = System.currentTimeMillis() - sendTime;
buffer = ByteBuffer.allocate(12); // redefine our buffer
buffer.putInt(1); // write opcode 1 to the buffer.
buffer.putLong(diff*2); // write the ms change to the buffer.
// Note that the MS change is an estimated "round-trip". That is, it takes the time it took for the client to send us
// it's packet and doubles it to account for the time it'll take to send it back.
out.write(buffer.array());
out.flush(); // Finally, flush (write) the data to the stream.
PingServer.println("Received "+(in.available()+12)+" bytes from "
+pClient.getInetAddress().getCanonicalHostName()
+"("
+pClient.getInetAddress().getHostAddress()
+")"
+ " - (12 bytes of data received in "+diff+" ms).");
break; // we're done now, so exit out.
} catch (BufferOverflowException e) { // if we get more than the bytes we expect, we could be getting flooded! break.
try {
PingServer.println("Received "+(in.available()+12)+" bytes from "
+pClient.getInetAddress().getCanonicalHostName()
+"("
+pClient.getInetAddress().getHostAddress()
+")"
+"! Closing connection!", true);
} catch (IOException e1) {
// ignore exception
} finally {
break; // break out of the loop, regardless of what happens, if we reach the BOE.
}
} catch (Exception e) { break; } // Break the loop if we error
}
// Close stuff, and then make this thread die.
try {
in.close();
out.close();
pClient.close();
Thread.currentThread().join();
} catch (Exception e) {
// ignore all exceptions
}
}
}














