2017-10-01 6 views
1

Je tente de créer une application client-serveur simple pour la discussion globale J'obtiens l'erreur suivante lorsque je quitte la connexion côté client.Application de chat client-serveur Java obtenant java.net.SocketException: Socket fermé

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) 

et en cas de panne client sans utiliser Quit cette erreur

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(); 
    } 
} 
} 

Comment gérer de telles situations où Socket est fermé lorsqu'il est utilisé par InputStreamReader

Répondre

0

SocketClosedException signifie que vous fermé la prise, à writeMessage.close(), puis continué à l'utiliser, à readMessage.readUTF(). C'est un bug dans votre code. Vous devrez trier les threads de lecture et d'écriture qui feront la fermeture, et ce ne devrait être que l'un d'entre eux, et pas pendant que l'autre est toujours en cours d'exécution.

Le EOFException est exactement ce à quoi vous devez vous attendre lorsque vous appelez readUTF() sur une connexion qui a déjà été fermée par le pair. Attrapez-le et manipulez-le séparément.

+0

Ok Mais comment gérer cela comme readMessage.readUTF() continue d'attendre un message et même quand je ferme les flux à la fin de la fonction d'exécution de ReadFromServer la boucle ne se termine qu'après l'exception – sudojdoe

+0

Err, 'catch (EOFException exc) { Pause; } 'si vous êtes dans la boucle, ou omettez le' break' si vous êtes à l'extérieur. Pas de mystère. – EJP