2015-06-24 105 views
-1

我正嘗試創建一個多線程服務器和客戶端對。這兩個類都是繼承的方法,用於寫入和從一個普通類讀取..我無法正確工作,並且正在接收空指針異常。 這裏是我的代碼:Java多線程服務器/客戶端邏輯不工作

//服務器和客戶端的常規類

package server; 

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 
import exception.AutoException; 

public class DefaultSocketClient extends Thread { 
    protected ObjectInputStream ois; 
    private ObjectOutputStream oos; 
    private Socket sok; 

    public DefaultSocketClient(Socket sok) { 
     this.sok = sok; 
    } 
public void run() { 
    openConnection(); 
    handleSession(); 
    // closeSession(); 
} 

/* 
* this methods opens connection 
*/ 

public void openConnection() { 
    try { 
     ois = new ObjectInputStream(sok.getInputStream()); 
     oos = new ObjectOutputStream(sok.getOutputStream()); 
    } catch (IOException e) { 
     try { 
      throw new AutoException("OpenConnectionException"); 
     } catch (AutoException e1) { 
      e1.printStackTrace(); 
     } 
    } 
} 

public void handleSession() { 
    Object input; 
    try { 
     while ((input = ois.readObject()) != null) { 
      handleInput(input); 
     } 
    } catch (Exception e) { 
     try { 
      throw new AutoException("HandleSessionException"); 
     } catch (AutoException e1) { 
      e1.printStackTrace(); 
     } 
    } 

} 

private void handleInput(Object newInput) { 
    System.out.println(newInput); 

} 

public void sendOutput(Object newOutput) { 
    try { 
     oos.writeObject(newOutput); 
    } catch (IOException ioe) { 
     try { 
      throw new AutoException("ObjectOutputException"); 
     } catch (AutoException e1) { 
      e1.printStackTrace(); 
     } 
    } 
} 

/** 
* This method closes the Session between client and server 
*/ 
public void closeSession() { 
    try { 
     ois.close(); 
     ois.close(); 
     sok.close(); 
    } catch (IOException e) { 
     try { 
      throw new AutoException("SessionCloseException"); 
     } catch (AutoException e1) { 
      e1.printStackTrace(); 
     } 
    } 

} 

}

//客戶

/* 
    * creating client 
    */ 
    public AutoClientSocket() { 
     try { 
      clientSocket = new Socket(InetAddress.getLocalHost(), 
        DEFAULT_PORT_NO); 
      readFromConsole = new BufferedReader(new InputStreamReader(
        System.in)); 
     } catch (Exception e) { 
      try { 
       throw new AutoException("AutoServerConnectionException"); 
      } catch (AutoException e1) { 
       e1.printStackTrace(); 
      } 

     } 
    } 

    // starting the client 
    public void startAutoClient() { 
     try { 
      defaultSocketClient = new DefaultSocketClient(clientSocket); 
      defaultSocketClient.start(); 
      System.out.println("Client started..."); 
      defaultSocketClient.closeSession(); 

//   performOperation(); 
     } catch (Exception e) { 
      try { 
       throw new AutoException("ConnectionException"); 
      } catch (AutoException e1) { 
       e1.printStackTrace(); 
      } 
     } 

    } 


    public void performOperation() { 
     // methods for client operations. 

    } 

} 

//服務器

public class AutoServerSocket { 

private int DEFAULT_PORT_NO = 7900; 
private static ServerSocket autoServer; 
ObjectOutputStream oos; 
ObjectInputStream ois; 

private DefaultSocketClient defaultSocketClient; 
BuildAuto build = new BuildAuto(); 
FileIO io = new FileIO(); 

// creating server 
public AutoServerSocket() { 
    try { 
     autoServer = new ServerSocket(DEFAULT_PORT_NO); 

     System.out.println("Server started..."); 
    } catch (Exception e) { 
     try { 
      throw new AutoException("AutoServerConnectionException"); 
     } catch (AutoException e1) { 
      e1.printStackTrace(); 
     } 

    } 
} 

// starting the server 
public void startAutoServer() { 
    Socket sok; 
    while (true) { 
     try { 
      sok = autoServer.accept(); 
      defaultSocketClient = new DefaultSocketClient(sok); 
      defaultSocketClient.start(); 
      System.out.println("Connection Established...."); 
      defaultSocketClient.sendOutput(generateAutoWelcome()); 
      defaultSocketClient.handleSession(); 
      defaultSocketClient.closeSession(); 
     } catch (IOException e) { 
      try { 
       throw new AutoException("ConnectionException"); 
      } catch (AutoException e1) { 
       e1.printStackTrace(); 
      } 
     } 
    } 
} 

/** 
* This method generates Welcome message for AutoWorld 
*/ 
private String generateAutoWelcome() { 
    return "--------Welcome to AutoWorld-----------"; 
} 

}

我在服務器收到以下異常 - >

Exception in thread "main" java.lang.NullPointerException 
    at server.DefaultSocketClient.sendOutput(DefaultSocketClient.java:64) 
    at server.AutoServerSocket.startAutoServer(AutoServerSocket.java:51) 
    at driver.ServerDriver.main(ServerDriver.java:11) 

在線路:

oos.writeObject(newOutput); 

我清楚在這裏做得不對,因爲我不能夠接受的對象我在客戶端發送。有人可以幫幫我嗎?

感謝

+1

異常跟蹤?在代碼中標出發生異常的行 –

+0

我在主帖中對其進行了編輯。感謝 – k19

+0

您在'startAutoClient'和'startAutoServer'中創建了一個新的'DefaultSocketClient',但是您不會調用'start'。相反,您從當前實例調用start,從不調用您在方法中創建的實例。我相信你的問題在那裏 –

回答

0

你的問題來自於有:

defaultSocketClient = new DefaultSocketClient(sok); 
    start(); 
    System.out.println("Connection Established...."); 
    sendOutput(generateAutoWelcome() + generateMainMenu()); 

您正在創建一個defaultSocketClient來處理客戶端創建的套接字,但你不要用它做任何事情。

通過

defaultSocketClient = new DefaultSocketClient(sok); 
    defaultSocketClient.start(); 
    System.out.println("Connection Established...."); 
    defaultSocketClient.sendOutput(generateAutoWelcome() + generateMainMenu()); 

這種替換這些行應該解決您的NullPointerException錯誤。

這裏還是有一些架構問題。 你應該爲你的服務器套接字建立一個線程,該線程在sok = autoServer.accept();上循環,但你不必在服務器上擴展DefaultSocketClient。您的服務器將基本等待新連接並創建DefaultSocketClient的新實例。 如果您想稍後重用它們,您的服務器還應該存儲DefaultSocketClient實例。否則,你應該在sendOutput()調用之後調用closeSession()

此代碼似乎是爲了學習的目的,所以它使用基本的Java套接字很好,但如果你不想做一個真正的/ multiclient /可縮放的客戶端服務器應用程序,我建議你使用一個庫。

Java的網絡庫:

  • Netty真的強大的lib,但可能很難proberly配置和真的很低的水平。
  • Kryonet易於使用一些很酷的功能,如對象序列化或主機發現。高級lib可以幫助您創建少量的客戶端和服務器。
+0

感謝您解釋這個如此好......但我認爲這就是我之前所做的事情。上面發佈的代碼稍微有所改變,因爲我一直在對它進行調試......我在主要文章中更新了這一個。我認爲這就是你所說的,但這仍然行不通。 – k19