基本上,我正在编写一种双向通信客户端服务器程序。客户端向服务器发送请求,服务器相应地做出响应。这些请求与在服务器上存储的令牌列表中添加或删除令牌有关。客户端似乎工作正常,正在将请求发送到服务器。但是,似乎服务器未从客户端收到任何请求,我也不知道为什么。我已经附上了代码:
客户
package;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class TokenClient {
private static final int PORT_NUMBER = 9999;
private Socket socket;
private InputStream inStream;
private OutputStream outStream;
private Scanner inStreamScanner;
private PrintWriter outStreamPrinter;
public static void main(String[] args) {
new TokenClient().go();
}
void go() {
try {
System.out.println(
"Enter commands of the form \"CONNECT IP-address\", \"SUBMIT token\", \"REMOVE token\" or \"QUIT\"\n");
Scanner consoleScanner = new Scanner(System.in);
// java.io.BufferedReader consoleInputReader = new
// BufferedReader(new InputStreamReader(System.in));
String command = "";
while (!command.equals("QUIT") && consoleScanner.hasNextLine()) {
command = consoleScanner.nextLine(); // consoleInputReader.readLine();
processCommand(command);
}
System.out.println("Goodbye!");
consoleScanner.close();
} catch (IOException e) {
System.out.println("An exception occurred: " + e);
e.printStackTrace();
}
}
void processCommand(String userCommand) throws IOException {
if (userCommand.startsWith("SUBMIT"))
sendMessageToServer(userCommand);
else if (userCommand.startsWith("REMOVE"))
sendMessageToServer(userCommand);
else if (userCommand.equals("QUIT"))
closeConnectionToServer();
else if (userCommand.startsWith("CONNECT")) {
closeConnectionToServer();
connectToServer(userCommand);
} else
System.out.println("Invalid user command: " + userCommand);
}
void closeConnectionToServer() {
if (socket != null && !socket.isClosed()) {
try {
System.out.println("Disconnecting from server...");
sendMessageToServer("QUIT");
socket.close();
System.out.println("Connection to server closed.");
} catch (IOException e) {
System.out.println("An exception occurred: " + e);
e.printStackTrace();
}
}
}
void connectToServer(String connectCommand) throws IOException {
String ipAddress = connectCommand.substring(8).trim();
System.out.println("Connecting to server at " + ipAddress + ", port " + PORT_NUMBER + "...");
socket = new Socket(ipAddress, PORT_NUMBER);
inStream = socket.getInputStream();
outStream = socket.getOutputStream();
inStreamScanner = new Scanner(inStream);
outStreamPrinter = new PrintWriter(outStream);
System.out.println("Connected to server.");
}
void sendMessageToServer(String command) {
System.out.println("Sending message to server: " + command + "...");
if (socket == null || socket.isClosed())
System.out.println("Not possible - not connected to a server");
else {
outStreamPrinter.println(command); // send the message to the server
// NB: client doesn't check if tokens are valid
outStreamPrinter.flush(); // do so immediately
// Receive response from server:
if (!command.equals("QUIT") && inStreamScanner.hasNextLine()) {
String response = inStreamScanner.nextLine();
System.out.println("Response from server: " + response);
}
}
}
}
服务器
package;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;
public class server {
private static Socket s;
private static Scanner inStreamScanner;
private static int PORT_NUMBER = 9999;
private static InputStream inStream;
private static OutputStream outStream;
private static PrintWriter outStreamPrinter;
private static ArrayList<String> ts = new ArrayList<String>();
public static void main(String[] args) throws IOException{
ServerSocket ss = new ServerSocket(PORT_NUMBER);
server serverInstance = new server();
server.s = ss.accept();
System.out.println("Client connected");
inStream = s.getInputStream();
outStream = s.getOutputStream();
inStreamScanner = new Scanner(inStream);
outStreamPrinter = new PrintWriter(outStream);
serverInstance.run();
}
public void run() {
try {
try {
doService();
} finally {
s.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
public void doService() throws IOException{
while(true) {
if(inStreamScanner.hasNext())
return;
else {
outStreamPrinter.println("NO REQUEST");
outStreamPrinter.flush();
String request = inStreamScanner.next();
outStreamPrinter.println("Request received: " +request);
outStreamPrinter.flush();
handleServerRequest(request);
}
}
}
public void handleServerRequest(String request) throws IOException{
if(request.startsWith("SUBMIT")) {
String token = extractNum(request);
addtoTS(token);
} else if(request.startsWith("REMOVE")) {
String token = extractNum(request);
removefromTS(token);
} else if(request.startsWith("QUIT")) {
s.close();
} else {
outStreamPrinter.println("UNKNOWN REQUEST");
outStreamPrinter.flush();
}
}
public String extractNum(String request) {
String str = request;
String numberOnly = str.replaceAll("[^0-9]", " ");
return numberOnly;
}
public void addtoTS(String token) {
if(ts.contains(token)) {
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}else {
ts.add(token);
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}
}
public void removefromTS(String token) {
if(ts.contains(token)) {
ts.remove(token);
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}else {
outStreamPrinter.println("ERROR: TOKEN NOT FOUND");
outStreamPrinter.flush();
}
}
}
答案 0 :(得分:0)
我还没有运行代码,但是您在服务器端的doService()
方法中似乎存在问题。您有一个无限循环,但是一旦输入流接收到新的换行符(客户端发送请求时),整个方法就会返回(因此程序也将退出)。因此,当您的程序从客户端收到第一个命令时,它似乎会退出。我还建议更轻柔地关闭(即,检查循环的结束而不是直接关闭套接字)。
因此,我将定义一个私有类变量boolean listening;
或类似的东西。然后,在main()
方法中,在套接字初始化后(客户端已连接时)将其设置为true
。
将您的doService()
更改为类似于以下内容的内容:
public void doService() throws IOException
{
while(listening)
{
if(inputStreamReader.hasNext())
{
String request = inStreamScanner.next();
outStreamPrinter.println("Request received: " +request);
outStreamPrinter.flush();
handleServerRequest(request);
}
}
}
并更改您处理QUIT
命令的方式:
来自
else if(request.startsWith("QUIT"))
{
s.close();
}
到
else if(request.startsWith("QUIT"))
{
listening = false;
}
套接字将被finally
中的run()
关闭。