服务器未从客户端接收请求

时间:2019-11-17 17:14:26

标签: java eclipse tcp server client

基本上,我正在编写一种双向通信客户端服务器程序。客户端向服务器发送请求,服务器相应地做出响应。这些请求与在服务器上存储的令牌列表中添加或删除令牌有关。客户端似乎工作正常,正在将请求发送到服务器。但是,似乎服务器未从客户端收到任何请求,我也不知道为什么。我已经附上了代码:

客户

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();
        }
    }
}

1 个答案:

答案 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()关闭。