Last active
February 17, 2018 05:26
-
-
Save tjhv/a558972f794f912da4690b8144d3f1d3 to your computer and use it in GitHub Desktop.
Old snippet from back in the day.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author tjhv | |
* @version 1.2, 09/18/2008 | |
* @since 1.0 | |
*/ | |
import java.nio.ByteBuffer; | |
import java.nio.channels.FileChannel; | |
import java.nio.channels.ServerSocketChannel; | |
import java.nio.channels.SocketChannel; | |
import java.nio.channels.Selector; | |
import java.nio.channels.SelectionKey; | |
import java.io.FileReader; | |
import java.io.BufferedReader; | |
import java.util.Iterator; | |
import java.util.Set; | |
import java.util.HashMap; | |
import java.util.ArrayList; | |
public class Server { | |
/** | |
* HashMap connections will be stored in, capacity of 1024. | |
*/ | |
private static HashMap<Integer, SocketChannel> client = new HashMap<Integer, SocketChannel>(); | |
/** | |
* ArrayList banned hosts will be stored in. | |
*/ | |
private static ArrayList<String> banned = new ArrayList<String>(); | |
/** | |
* Starts listening on the valid port (0-65535) specified. | |
* Choose 0 for a random port, although it is depreciated | |
* as you will not be notified on what port was selected. | |
* | |
* @param args The port of which you want to run the server on. | |
* @throws IOException If an input or output error occurs, usually when a connection | |
* is forcibly closed by the remote host. | |
* @throws BindException Exception will be thrown if you choose a port already in use. | |
*/ | |
public static void main(String[] args) throws Exception { | |
try { | |
Selector selector = Selector.open(); | |
ServerSocketChannel server = ServerSocketChannel.open(); | |
server.configureBlocking(false); | |
/** | |
* Attempts to listen on the port you chose. | |
*/ | |
server.socket().bind(new java.net.InetSocketAddress(Integer.parseInt(args[0]))); | |
if (server.socket().isBound()) { | |
/** | |
* If the server is listening on the local address, will return true and print message in console. | |
*/ | |
System.out.println("Listening on port " + Integer.parseInt(args[0])); | |
} | |
SelectionKey serverkey = server.register(selector, SelectionKey.OP_ACCEPT); | |
/** | |
* Calling this method is very import as it loads banned hosts, etc. | |
*/ | |
initialize(); | |
while (true) { | |
/** | |
* Forever looping to keep listening for incomming connections. | |
*/ | |
selector.select(); | |
Set keys = selector.selectedKeys(); | |
for (Iterator it = keys.iterator(); it.hasNext();) { | |
SelectionKey key = (SelectionKey) it.next(); | |
it.remove(); | |
if (!key.isValid()) { | |
continue; | |
} | |
if (serverkey == key) { | |
if (key.isAcceptable()) { | |
/** | |
* If the key is acceptable than we will accept the client. | |
*/ | |
SocketChannel socket = server.accept(); | |
socket.configureBlocking(false); | |
/** | |
* We must register the key for reading. | |
*/ | |
key = socket.register(selector, SelectionKey.OP_READ); | |
/** | |
* Get a new index for this client which we will use when referencing to it. | |
*/ | |
int index = getIndex(); | |
/** | |
* Assign the index to this client. | |
*/ | |
client.put(index, socket); | |
if (banned.contains(address(index))) { | |
/** | |
* If the remote host is listed in our banned hosts array, this is where we will handle the connection. | |
*/ | |
System.out.println("Connection rejected from " + address(index)); | |
remove(index); | |
continue; | |
} | |
if (index == -1) { | |
System.out.println("Connection closed from " + address(index)); | |
remove(index); | |
continue; | |
} | |
System.out.println("Connection recieved from " + address(index)); | |
} | |
} else { | |
/** | |
* Creates the socket from the key's channel, which will be the previous socket we've made. | |
*/ | |
SocketChannel socket = (SocketChannel) key.channel(); | |
if (!key.isReadable()) { | |
continue; | |
} | |
ByteBuffer buffer = ByteBuffer.allocate(512); | |
int read = new Integer(); | |
try { | |
read = socket.read(buffer); | |
} catch (Exception exception) { | |
/** | |
* If an exception is cought, more than likely it is telling you that the connection was forcibly closed, | |
* printing the error would be far too unnecessary. | |
* <p> | |
* Since the connection was closed, we must cancel the key and close the connection from our end. | |
*/ | |
key.channel().close(); | |
key.cancel(); | |
continue; | |
} | |
if (read == -1) { | |
key.channel().close(); | |
key.cancel(); | |
continue; | |
} | |
} | |
} | |
} | |
} catch (Exception exception) { | |
/** | |
* Usually, when an exception is cought here, it is because the port you specified is already in use. | |
*/ | |
exception.printStackTrace(); | |
} | |
} | |
/** | |
* Initializes the banned hosts array, aswell as many other | |
* variables to be loaded at start up. | |
* | |
* @since 1.0 | |
*/ | |
public static void initialize() { | |
try { | |
BufferedReader in = new BufferedReader(new FileReader("data/banned/host.dat")); | |
String line = new String(); | |
while ((line = in.readLine()) != null) { | |
banned.add(line); | |
} | |
} catch (Exception exception) { | |
System.out.println("Error while loading banned hosts."); | |
} | |
} | |
/** | |
* Gets the host the given client is connected from. | |
* Ideal use for checking their host against that of the banned. | |
* | |
* @param client The client to get the host for. | |
* @return Returns the host the client is connected from. | |
* @since 1.0 | |
*/ | |
public static String address(int index) { | |
return client.get(index).socket().getInetAddress().getHostAddress(); | |
} | |
/** | |
* Loops through the client HashMap and checks for a free | |
* index that can be used. | |
* | |
* @return Returns an index not in use. | |
* @since 1.0 | |
*/ | |
public static int getIndex() { | |
for (int i = 0; i < 1024; i++) { | |
if (client.get(i) == null) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
/** | |
* Terminates the given clients connection and frees | |
* the index to be used by another connection. | |
* | |
* @param index The index of the client to be removed. | |
* @since 1.0 | |
*/ | |
public static void remove(int index) { | |
if (client.get(index) == null) { | |
return; | |
} | |
try { | |
client.get(index).close(); | |
} catch (Exception exception) { | |
} | |
client.remove(index); | |
} | |
public static void read(int index) { | |
} | |
public static void write(int index) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment