import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.StringBuilder;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Server {
private final int port;
private final ByteBuffer readBuffer;
private final Map<SelectionKey, BufferEntry> buffers;
Server(int port) throws IOException {
this.port = port;
readBuffer = ByteBuffer.allocate(10000);
buffers = new HashMap<SelectionKey, BufferEntry>();
}
public void go() throws IOException {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(port);
ss.bind(isa);
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Listening on port " + port);
while (true) {
if (selector.select() != 0) {
Set<SelectionKey> keys = selector.selectedKeys();
for (SelectionKey key : keys) {
if (key.isAcceptable()) {
accept(selector, ss.accept());
} else if (key.isReadable()) {
read(selector, key);
} else if (key.isWritable()) {
write(selector, key);
}
}
keys.clear();
}
}
}
private void accept(Selector selector, Socket s) throws IOException {
System.out.println("Got connection from " + s);
SocketChannel sc = s.getChannel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
}
private void read(Selector selector, SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
if (readBuffer.limit() == 0) {
key.cancel();
Socket s = sc.socket();
s.close();
} else {
readBuffer.clear();
sc.read(readBuffer);
readBuffer.flip();
String filePath = "./mountain.jpg";
System.out.println("Sending file '" + filePath + "' to " + sc);
sc.register(selector, SelectionKey.OP_WRITE);
buffers.put(key, new BufferEntry(filePath));
}
}
private class BufferEntry {
private FileChannel chan;
private ByteBuffer buf;
public BufferEntry(String filePath) throws IOException {
chan = new RandomAccessFile(filePath, "r").getChannel();
buf = chan.map(FileChannel.MapMode.READ_ONLY, 0, chan.size());
}
public void close() throws IOException {
chan.close();
}
}
private void write(Selector selector, SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
BufferEntry entry = buffers.get(key);
if (entry == null) {
key.cancel();
Socket s = sc.socket();
s.close();
} else {
sc.write(entry.buf);
if (entry.buf.hasRemaining()) {
sc.register(selector, SelectionKey.OP_WRITE);
} else {
key.cancel();
buffers.remove(key);
Socket s = sc.socket();
s.flush();
s.close();
}
}
}
public static void main(String[] args) {
try {
Server serv = new Server(9999);
serv.go();
} catch (IOException e) {
System.err.println("Error in server");
System.err.println(e.getMessage());
System.exit(1);
}
}
}