2015-06-24 109 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