2015-12-21 562 views
0

我寫了簡單的客戶端serwer,但不幸的是,我做到了如此混亂和很差,所以我決定寫一切從頭開始。我想寫信給兩個方向進行通信,並斷開和連接一個新的客戶端。這意味着客戶端或服務器發送一條消息並且一個適當的讀取它。在開始的時候所有的作品,但是當我想關閉客戶端,我得到兩個錯誤:客戶端 - 服務器雙向通信

java.net.SocketException: Socket closed readSocketData() 
java.net.SocketException: Socket closedwriteData(String data) 

我當然明白這些錯誤是什麼意思,但我不明白爲什麼他們顯示出來,因爲我有一個while循環中,我檢查客戶端是否連接。後來當我嘗試連接一個新的客戶端時,一切都崩潰了。 我寫了3類客戶端,服務器和通信。客戶端和服務器從通信中繼承(用於打開和讀取數據流的方法)。這一切看起來像:

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server extends Communication{ 

ServerSocket serverSocket; 
Socket listener; 
boolean listenerLife; 

public Server(int port) { 

    try { 
     serverSocket = new ServerSocket(port); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
} 

public void startListener(){ 

    while (true){ 
     try { 
      listener = serverSocket.accept(); 
      listenerLife = true; 
     } catch (IOException e) { 
      System.out.println(e); 
     } 
     openWriter(listener); 
     openReader(listener); 
     writeServerDataThread(); 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       readData(); 
      } 
     }).start(); 
    } 

} 

public void writeServerDataThread(){ 
    openLocalReader(); 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (true){ 
       String data = readLocalData(); 
       writeData(data); 
      } 
     } 
    }).start(); 
} 


public void readData(){ 
    while (listenerLife){ 
     String data = readSocketData(); 

     if("exit".equals(data) || data == null){ 
      try { 
       listenerLife = false; 
       listener.close(); 
      } catch (IOException e) { 
       System.out.println(e); 
      } 
     } 
     else { 
      System.out.println(data); 
     } 

    } 
} 



public void writeData(String data){ 
    try { 
     writer.writeBytes(data + '\n'); 
     writer.flush(); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
} 



public static void main(String[] args) { 
    Server server = new Server(8080); 

    server.startListener(); 


} 
} 
import java.io.IOException; 
import java.net.Socket; 

public class Client extends Communication{ 

Socket clientSocket; 
boolean clientLive; 

public Client(String hostName, int port) { 

    try { 
     clientSocket = new Socket(hostName, port); 
     clientLive = true; 
    } catch (IOException e) { 
     System.out.println(e + "Client(String hostName, int port)"); 
    } 

} 

public boolean closeConnection(String data){ 
    if("exit".equals(data) || data == null){ 
     try { 
      writeData("Zamykam klienta"); 
      clientSocket.close(); 
      clientLive = false; 
      return false; 
     } catch (IOException e) { 
      System.out.println(e + "closeConnection(String data)"); 
     } 
    } 
    return true; 
} 

public void readClientData(){ 
    new Thread(new Runnable() { 
     @Override 
     public synchronized void run() { 
      openLocalReader(); 
      while (!clientSocket.isClosed()){ 
       String data = readLocalData(); 

       if(closeConnection(data)){ 
        writeData(data); 
       } 
      } 
     } 
    }).start(); 

} 

public void readServerDataThread(){ 
    new Thread(new Runnable() { 
     @Override 
     public synchronized void run() { 
      while (!clientSocket.isClosed()){ 
       String data = readSocketData(); 

       if(closeConnection(data)){ 
        System.out.println(data); 
       } 
      } 
     } 
    }).start(); 

} 

public void writeData(String data){ 
    try { 
     writer.writeBytes(data + '\n'); 
     writer.flush(); 
    } catch (IOException e) { 
     System.out.println(e + "writeData(String data)"); 
    } 
} 

public static void main(String[] args) { 
    final Client client = new Client("localhost", 8080); 
    client.openReader(client.clientSocket); 
    client.openWriter(client.clientSocket); 
    client.readServerDataThread(); 

    client.readClientData(); 


} 
} 
import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.Socket; 

public class Communication { 

BufferedReader reader; 
BufferedReader localReader; 
DataOutputStream writer; 

public void openReader(Socket incomingSocket){ 

    try { 
     reader = new BufferedReader(new InputStreamReader(incomingSocket.getInputStream())); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
} 

public void openWriter(Socket incomingSocket){ 

    try { 
     writer = new DataOutputStream(incomingSocket.getOutputStream()); 
    } catch (IOException e) { 
     System.out.println(e); 
    } 
} 

public void openLocalReader(){ 
    localReader = new BufferedReader(new InputStreamReader(System.in)); 
} 

public String readLocalData(){ 
    String data = null; 

    try { 
     data = localReader.readLine(); 
    } catch (IOException e) { 
     System.out.println(e + " readLocalData()"); 
    } 
    return data; 
} 

public String readSocketData(){ 
    String data = null; 

    try { 
     data = reader.readLine(); 
    } catch (IOException e) { 
     System.out.println(e + " readSocketData()"); 
    } 
    return data; 
} 

}

回答

1
java.net.SocketException: Socket closed readSocketData() 
java.net.SocketException: Socket closed writeData(String data) 

我當然明白這些錯誤意味着

他們的意思是你關閉套接字,並繼續使用它。

但我不明白他們爲什麼會出現,因爲我有一個while循環,我檢查客戶端是否連接。

不,你不會。你有一個while循環,其中你檢查客戶端插座是否仍然是開放,這是不一樣的東西...但在任何情況下,不會阻止你使用一個封閉的插座裏面循環,例如在關閉closeConnection()後,它的返回值應該回到前面,無疑會造成混淆,並且由兩個線程調用,據我所知。

+0

我不明白。我應該怎麼做? – Slovvik