I have this application that has a server that connects multiple clients on specific ports. As ServerSocket can be blocking and cant be used with multiple ports, I've gone with ServerSocketChannel from the Java NIO library. I've used the idea from this post on SO (Java Server - Multiple ports?).
Firstly for news servers, it reads from a file and sends it to the main server which then combines all the data sent by those servers.
The second part of this program is wherein the client requests the data from the server and the main server then sends the data of the combined file from the servers.
Server
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;
import java.*;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Set;
public class dummyServer {
public static void main(String[] args) throws IOException
{
int ports[] = new int[] {5056, 4587, 5057};
Selector selector = Selector.open();
for (int port:ports){
ServerSocketChannel socketChannel = ServerSocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.socket().bind(new InetSocketAddress(port));
socketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
while (selector.isOpen()) {
try {
selector.select();
Set readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
System.out.println(readyKeys.size());
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
if (key.isAcceptable()) {
SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
Socket socket = socketChannel.socket();
System.out.println("Accepted From: " + socket);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
Thread t = new ClientHandler(socket, dis, dos);
t.start();
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}
// ClientHandler class
class ClientHandler extends Thread
{
final DataInputStream dis;
final DataOutputStream dos;
Socket s;
// Constructor
public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos) throws IOException {
this.s = s;
this.dis = dis;
this.dos = dos;
}
@Override
public void run()
{
String received;
while (true)
{
try {
switch (s.getLocalPort()) {
case 5056:
received = dis.readUTF();
System.out.println(received);
FileWriter fw = new FileWriter("compiled.txt", true);
fw.write(received);
fw.close();
break;
case 4587:
try {
String content = readFile("compiled.txt", StandardCharsets.UTF_8);
dos.writeUTF(content);
}
catch (Exception e){
e.printStackTrace();
System.exit(0);
}
finally {
dos.flush();
dos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
News
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
// Client class
public class dummyNews
{
public static void main(String[] args) throws IOException
{
try
{
Scanner scn = new Scanner(System.in);
File file = new File("news.txt");
long timeStamp = 0;
String data = null;
// getting localhost ip
InetAddress ip = InetAddress.getByName("localhost");
Socket s = new Socket(ip, 5056);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
// the following loop performs the exchange of
// information between client and client handler
while(true){
long newStamp = file.lastModified();
if(timeStamp != newStamp){
data = readFile("news.txt", StandardCharsets.US_ASCII);
dos.writeUTF(data);
timeStamp = newStamp;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
Client
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class clientDummy {
// different name because i don't want to
// overwrite the one used by server...
public final static int FILE_SIZE = 6022386; // file size temporary hard coded
public clientDummy() throws UnknownHostException {
}
// should bigger than the file to be downloaded
public static void main (String [] args ) throws IOException {
final int SOCKET_PORT = 4587; // you may change this
InetAddress ip = InetAddress.getByName("localhost");
final String FILE_TO_RECEIVED = "source-downloaded.txt"; // you may change this, I give a
DataInputStream dis = null;
Socket sock = null;
try {
sock = new Socket(ip, SOCKET_PORT);
dis = new DataInputStream(sock.getInputStream());
String rec = dis.readUTF();
System.out.println(rec);
}
finally {
dis.close();
}
}
}
Server Stack Trace
Accepted From: Socket[addr=/127.0.0.1,port=56607,localport=4587]
java.nio.channels.ClosedChannelException
at sun.nio.ch.SocketChannelImpl.ensureWriteOpen(Unknown Source)
at sun.nio.ch.SocketChannelImpl.write(Unknown Source)
at java.nio.channels.Channels.writeFullyImpl(Unknown Source)
at java.nio.channels.Channels.writeFully(Unknown Source)
at java.nio.channels.Channels.access$000(Unknown Source)
at java.nio.channels.Channels$1.write(Unknown Source)
at java.io.DataOutputStream.write(Unknown Source)
at java.io.DataOutputStream.writeUTF(Unknown Source)
at java.io.DataOutputStream.writeUTF(Unknown Source)
at ClientHandler.run(dummyServer.java:108)
Also some of the times after executing the dummyNews.java I get a NullPointerException on the main server.
StackTrace
java.lang.NullPointerException
at dummyServer.main(dummyServer.java:50)