我收到一个我无法解决的异常。
package advanced.net;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class LottoClient {
private InetAddress serverAddress;
private int serverPort = LottoProtocol.SERVER_PORT;
public static void main(String[] args) {
System.out.println("Starting Client");
LottoClient lottoClient1 = null;
lottoClient1 = new LottoClient(); // This was not a TODO
lottoClient1.startClient(args);
}
public LottoClient() {
}
private String getTicketFromServer() {
String lotteryTicket = null;
BufferedReader reader = null; // to get response from server
PrintWriter writer = null; // to send request to server
System.out.println("Getting Ticket");
try {
Socket socket = new Socket(serverAddress, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(in));
writer = new PrintWriter(out, true); // true for autoflush
lotteryTicket = reader.readLine(); // read the response
} catch (java.io.IOException e) {
System.err.println("Error getting ticket");
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
if (writer != null) {
writer.close();
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
// TODO 08. Return the lottery ticket String.
return lotteryTicket;
}
/**
* configData[0] is the name or IP address of the server
*/
private void processConfigData(String configData[]) {
try {
// set address of server
if (configData != null && configData.length >= 1) {
serverAddress = InetAddress.getByName(configData[0]);
} else {
// default case is set in our protocol
String host = LottoProtocol.SERVER_HOST;
serverAddress = InetAddress.getByName(host);
}
} catch (java.net.UnknownHostException e) {
e.printStackTrace();
}
}
public void startClient(String args[]) {
processConfigData(args);
String lottoTicket = getTicketFromServer();
System.out.println(lottoTicket);
}
}
package advanced.net;
import java.util.*;
import java.net.*;
import java.io.*;
public class LottoServer {
// TODO 01. Make the handler a subclass of Thread.
private class ClientRequestHandler extends Thread {
private Socket socket = null;
public ClientRequestHandler() {
// Default Constructor
}
public ClientRequestHandler(Socket clientSocket) {
socket = clientSocket;
}
/**
* Generate a lotto ticket. Returns a formatted string containing 6
* numbers from 1 to 49.
*/
private String getTicket() {
int theNumbers[] = new int[LottoProtocol.NUM_OF_NUMBERS];
for (int i = 0; i < LottoProtocol.NUM_OF_NUMBERS; i++) {
int newNumber;
boolean isDuplicate = false;
do {
isDuplicate = false; // reset isDuplicate, in case it has
// been set to true
// we want the numbers to be in the range of 1 to maxValue
// 0 to 48, and then add 1 to make it 1 to 49
newNumber = (int) (numberGenerator.nextDouble()
* (LottoProtocol.MAX_VALUE - 1) + 1);
// Compare to the numbers entered previously, to make sure
// it is
// not a duplicate.
// If it is, then ignore it, and get a new random number.
for (int j = 0; j < i && !isDuplicate; j++) {
if (newNumber == theNumbers[j]) {
isDuplicate = true;
}
}
} while (isDuplicate);
theNumbers[i] = newNumber;
}
Arrays.sort(theNumbers);
StringBuffer sb = new StringBuffer();
sb.append("Your numbers are: ");
for (int k = 0; k < LottoProtocol.NUM_OF_NUMBERS; k++) {
sb.append(String.valueOf(theNumbers[k]) + " ");
}
return sb.toString();
}
private void handleClientRequests() {
BufferedReader reader = null; // to read client requests
PrintWriter writer = null; // to send back response
String request;
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(in));
writer = new PrintWriter(out, true); // true for autoflush
writer.println("LottoServer 1.2");
request = reader.readLine(); // read client request
if (request
.equalsIgnoreCase(LottoProtocol.TICKET_REQUEST_COMMAND)) {
writer.println(getTicket()); // process the request
}
} catch (IOException ioe) {
System.err.println("Error processing the request");
ioe.printStackTrace();
} finally {
try {
if (reader != null) {
// TODO 05. Close the reader.
reader.close();
}
if (writer != null) {
// TODO 06. Close the writer.
writer.close();
}
if (socket != null) {
// TODO 07. Close the client socket.
socket.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public void run() {
handleClientRequests();
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
public static void main(String[] args) {
LottoServer lottoServer1 = new LottoServer();
lottoServer1.startServer();
}
private Random numberGenerator = new Random(System.currentTimeMillis());
private ServerSocket serverSocket = null;
public LottoServer() {
}
private void acceptConnections() {
Socket clientSocket;
while (true) {
try {
// TODO 02. Get the socket from the client.
System.out.println("Socket Empty");
clientSocket = null;
clientSocket = serverSocket.accept();
System.out.println("Socket Captured");
// TODO 03. Create a new instance of the handler.
ClientRequestHandler handler = null;
handler = new ClientRequestHandler();
System.out.println("Handler Created");
handler.setSocket(clientSocket);
Thread thread = new Thread(handler);
System.out.println("Thread Created");
// TODO 04. Start the new thread.
thread.start();
System.out.println("Thread Started Created");
} catch (java.io.IOException e) {
System.err.println("Error setting up connection");
e.printStackTrace();
}
}
}
private void createServerSocket() {
try {
serverSocket = new ServerSocket(LottoProtocol.SERVER_PORT);
System.out.println("Socket Created");
} catch (java.io.IOException e) {
String error = "Error setting up connection" + e.getMessage();
System.err.println(error);
}
}
public void startServer() {
System.out.println("Server Started");
createServerSocket();
acceptConnections();
}
}
package advanced.net;
public class LottoProtocol {
public static final int MAX_VALUE = 49;
public static final int NUM_OF_NUMBERS = 6;
public static final String SERVER_HOST = "localhost";
public static final int SERVER_PORT = 5123;
public static final String TICKET_REQUEST_COMMAND = "GetTicket";
}
我已经编写了println语句来检查代码中的关键点。我相信这是我告诉线程在客户端连接后启动的地方,但是我无法跟踪空指针的来源。
答案 0 :(得分:0)
如果您附加了您提到的异常的堆栈跟踪,那将会很有帮助。但是把它放在一边,你的问题就在handleClientRequests()
类的ClientRequestHandler
方法中,可能 - 再次,没有堆栈跟踪,特别是在以下行中:
request = reader.readLine(); // read client request
从BufferedReader
JavaDocs,readline()
返回:
包含行内容的字符串,不包括任何行终止字符;如果已到达流的末尾,则为null。
因此,如果您的服务器收到空消息,则第一次调用readline()
将返回null,并在下一行:
if (request.equalsIgnoreCase(LottoProtocol.TICKET_REQUEST_COMMAND)) {
你将获得NullPointerException
。作为一个简单的修复,您可以反转此相等性检查并使用:
if (LottoProtocol.TICKET_REQUEST_COMMAND.equalsIgnoreCase(request)) {