1

I am Trying to create a simple client-server application for global chat I am getting the following error when quitting the connection from client Side.

java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:203)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:223)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at ReadFromServer.run(ChatClient.java:25)

and when client crashes without using Quit this error

java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at Clients.run(ChatServer.java:34)

ChatServer.java

import java.util.*;
import java.io.*;
import java.net.*;
class Clients extends Thread 
{
private static ArrayList<DataOutputStream> clientOutputStreams;
private DataInputStream dataInputStream;
private DataOutputStream dataOutputStream;
private Socket socket;
static
{
    clientOutputStreams=new ArrayList<>();
}
Clients(Socket socket)
{
    try
    {
        this.socket=socket;
        this.dataInputStream=new DataInputStream(socket.getInputStream());
        this.dataOutputStream=new DataOutputStream(socket.getOutputStream());
        clientOutputStreams.add(dataOutputStream);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
public void run()
{
    try
    {
        try
        {
            String message=dataInputStream.readUTF();
            while(!message.equalsIgnoreCase("quit"))
            {
                for(DataOutputStream dis:clientOutputStreams)
                {
                    dis.writeUTF(message);
                }
                message=dataInputStream.readUTF();
            }
            Thread.currentThread().interrupt();
        }
        finally
        {
            dataInputStream.close();
            dataOutputStream.close();
            clientOutputStreams.remove(clientOutputStreams.indexOf(dataOutputStream));
            socket.close();
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
}
public class ChatServer
{
    public static void main(String[] args)throws Exception
    {
    try
    {
        ServerSocket serverSocket=new ServerSocket(9000);
        while(true)
        {
            Socket s=serverSocket.accept();
            Clients client=new Clients(s);
            client.start();
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
}

ChatClient.java

import java.util.*;
import java.io.*;
import java.net.*;
class ReadFromServer extends Thread
{
private DataInputStream readMessage;
ReadFromServer(Socket socket)
{
    try
    {
        this.readMessage=new DataInputStream(socket.getInputStream());
    }
    catch(Exception e)
    {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
public void run()
{
    try
    {
        while(!Thread.currentThread().isInterrupted())
        {
            System.out.println(readMessage.readUTF());
        }
        readMessage.close();
        Thread.currentThread().interrupt();
        if(Thread.currentThread().isInterrupted())
            return;
    }
    catch(Exception e)
    {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
}
class WriteToServer extends Thread
{
private DataOutputStream writeMessage;
private String clientName;
private Socket socket;
WriteToServer(Socket socket,String clientName)
{
    try
    {
        this.socket=socket;
        this.writeMessage=new DataOutputStream(socket.getOutputStream());
        this.clientName=clientName;
    }
    catch(Exception e)
    {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
public void run()
{
    try
    {
        Scanner scanner=new Scanner(System.in);
        String message=scanner.nextLine();
        while(!message.equalsIgnoreCase("quit"))
        {
            writeMessage.writeUTF(clientName+":"+message);
            message=scanner.nextLine();
        }
        writeMessage.writeUTF(message);
        writeMessage.close();
        Thread.currentThread().interrupt();
        if(Thread.currentThread().isInterrupted())
            return;
    }
    catch(Exception e)
    {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
}
public class ChatClient
{
public static void main(String[] args)
{
    try
    {
        Socket socket=new Socket("localhost",9000);
        try
        {
            System.out.print("Enter Your Name:");
            Scanner scanner=new Scanner(System.in);
            String clientName=scanner.nextLine();
            ReadFromServer rfs=new ReadFromServer(socket);
            WriteToServer wts=new WriteToServer(socket,clientName);
            wts.start();
            rfs.start();
            while(wts.isAlive());
            rfs.interrupt();
            System.out.println("End of Both Threads");
            //socket.close();
        }
        finally
        {
            socket.close();
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
}

How to handle such situations when Socket is closed when being used by InputStreamReader

1 Answer 1

0

SocketClosedException means that you closed the socket, at writeMessage.close(), and then continued to use it, at readMessage.readUTF(). It's a bug in your code. You will have to sort out which of the reader and writer threads should do the closing, and it should only be one of them, and not while the other is still running.

The EOFException is exactly what you should expect when you call readUTF() on a connection that has already been closed by the peer. Catch it and handle it separately.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok But how do I handle that as readMessage.readUTF() keeps waiting for a message and even when i close the streams at the end of ReadFromServer's run function the loop only ends after the exception
Err, catch (EOFException exc) { break; } if you're inside the loop, or omit the break if outside it. No mystery.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.