简体   繁体   English

服务器没有收到客户端的请求

[英]Server not receiving requests from client

Basically I'm writing a 2 way communication client server program.基本上我正在编写一个2路通信客户端服务器程序。 The client sends requests to the server and server responds accordingly.客户端向服务器发送请求,服务器做出相应的响应。 The requests have to do with adding or removing tokens from a list of tokens stored on the server.这些请求与从存储在服务器上的令牌列表中添加或删除令牌有关。 The client side seems to work fine, the requests are being sent to the server.客户端似乎工作正常,请求正在发送到服务器。 However it seems that the server is not receiving any request from the client and I have no idea why.但是,服务器似乎没有收到来自客户端的任何请求,我不知道为什么。 I've attached the code:我附上了代码:

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

server服务器

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

I haven't run the code, but there seems to be an issue in your doService() method on the server side.我没有运行代码,但服务器端的doService()方法似乎存在问题。 You have an infinite loop, but the entire method returns (and thus the program also quits) as soon as the input stream recieves a new line character (when the client sends a request).您有一个无限循环,但只要输入 stream 收到换行符(当客户端发送请求时),整个方法就会返回(因此程序也会退出)。 So, it seems your program would quit when it receives the first command from the client.因此,当您的程序收到来自客户端的第一个命令时,它似乎会退出。 I'd also recommend closing more gently (ie check in the loop for end rather than closing the socket directly).我还建议更温和地关闭(即检查循环是否结束,而不是直接关闭套接字)。

So, I'd define a private class variable boolean listening;所以,我会定义一个私有 class 变量boolean listening; or something like that.或类似的东西。 Then in the main() method, set it to true after the socket has been initialized (when the client has connected).然后在main()方法中,在套接字初始化后(当客户端连接时)将其设置为true

Change your doService() to something similar to the following:将您的doService()更改为类似于以下内容:

public void doService() throws IOException
{
  while(listening)
  {
    if(inputStreamReader.hasNext())
    {
      String request = inStreamScanner.next();
      outStreamPrinter.println("Request received: " +request);
      outStreamPrinter.flush();
      handleServerRequest(request);
    }
  }
}

And change how you handle the QUIT command:并更改您处理QUIT命令的方式:

from

else if(request.startsWith("QUIT"))
{
  s.close();
}

to

else if(request.startsWith("QUIT"))
{
  listening = false;
}

The socket will be closed by the finally in run() .套接字将被run()中的finally关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM