I am currently busy working on an instant messenger program using the UDP DatagramSocket
and DatagramPacket
instead of the usual connection-based Socket
and ServerSocket
. I need the server-side of the application to check the online status of its clients. I have attempted doing this by connecting to the server using the connection-based Socket
on the client side in a seperate thread (this connection serves no other purpose other than to determine the online status of the client.)
I am getting a java.net.SocketException: Socket closed
exeption on line 87, but no sockets are being closed... Please advise. Is there a better / easier way of checking the users online status? If not, then what is wrong with my code?
Server-side code for accepting new Socket
based connections in the UDP based IM:
//Server side handling new clients
private static class Listener implements Runnable {
private String IPCon = null;
private ServerSocket server;
@Override
public void run(){
Socket connection = null;
while(true){
try{
server = new ServerSocket(sGUI.onlinePort, 10); //onlinePort = 9337
connection = server.accept();
ClientHandler client = new ClientHandler(connection, ListPos);
clients.put(IPCon, client);
client.start();
try{
Thread.sleep(1_560);
}catch(InterruptedException ie){ }
}catch(IOException ioe){
JOptionPane.showMessageDialog(goo, ioe.getMessage(), "", JOptionPane.ERROR_MESSAGE);
}finally{
try {
if(connection != null)
connection.close();
}catch(IOException ieeo){ }
}
}
}
} //Listener
static class ClientHandler extends Thread {
private Socket client;
private ObjectInputStream input;
private ObjectOutputStream output;
private int ID;
private String IPAddress, joinDate;
ClientHandler(Socket sock, int index){
this.client = sock;
this.ID = index;
this.joinDate = new Date().toString();
this.IPAddress = client.getInetAddress().getHostAddress();
}
@Override
public void run(){
try{
try{
setupStreams(this.client);
whileChatting();
}catch(IOException ioe){
JOptionPane.showMessageDialog(goo, ioe.getLocalizedMessage() + ioe.getMessage(), "Streams error", JOptionPane.ERROR_MESSAGE);
ioe.printStackTrace();
}catch(ClassNotFoundException cnfe){
JOptionPane.showMessageDialog(goo, cnfe.getMessage(), "", JOptionPane.ERROR_MESSAGE);
}
}finally{
try{
closeConnections();
}catch(IOException ie){}
}
}
public void setupStreams(Socket socket) throws IOException {
output = new ObjectOutputStream(socket.getOutputStream());
output.flush();
input = new ObjectInputStream(socket.getInputStream());
}
private void closeConnections() throws IOException {
output.flush();
output.close();
input.close();
client.close();
}
//just used to ensure that the connection is not closed
public void whileChatting() throws IOException, ClassNotFoundException {
String message;
do{
message = (String) input.readObject(); //socket closed error here
JOptionPane.showMessageDialog(goo, message, "Message:", JOptionPane.PLAIN_MESSAGE);
}while(!message.equals("TERMINATE_CONNECTION"));
}
}
Client code for connecting to the server and maintaining the connection:
static class CheckServer extends Thread {
private Socket connection;
private ObjectInputStream input;
private ObjectOutputStream output;
private static boolean jumpStart = false;
@Override
public void run(){
while(true){
try{
connectToServer();
connected = true;
goo.setNotificationLabel("Connected to server!");
setupStreams(connection);
cGUI.getTextField().setEditable(true);
whileChatting();
}catch(IOException ioe){
cGUI.getTextField().setEditable(false);
for(int i = 60; i >= 0; i--){
if(jumpStart){
jumpStart = false;
break;
}
goo.setNotificationLabel("Error connecting to server... Trying again in " + i + " seconds");
try{ Thread.sleep(1_000);
}catch(InterruptedException ie){ }
}
}catch(ClassNotFoundException cnfe){
try {
whileChatting();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}finally{
if(connection != null){
try{
closeConnections();
}catch(IOException ioee){ goo.setNotificationLabel("Could not close socket..."); }
}
}
}
}
public static void jumpStart(){
jumpStart = true;
}
private void closeConnections() throws IOException {
output.flush();
output.close();
input.close();
connection.close();
}
private void whileChatting() throws IOException, ClassNotFoundException {
String message = null;
do{
message = (String) input.readObject();
}while(!message.equals("Terminate"));
}
private void connectToServer() throws IOException {
connection = new Socket(serverAddress, com.francois.m_app.server.sGUI.onlinePort);
myaddress = connection.getInetAddress().getHostAddress().toString();
}
private void setupStreams(Socket socket) throws IOException {
output = new ObjectOutputStream(socket.getOutputStream());
output.flush();
input = new ObjectInputStream(socket.getInputStream());
}
}