Java клиент читает неверные целые числа с сервера - PullRequest
0 голосов
/ 25 января 2020

Программа должна была быть относительно прямой. Цель состояла в том, чтобы иметь сервер, который периодически отправлял бы значение rgb (255 255 255) всем клиентам, которые к нему подключены. В приведенном ниже коде я упростил его до одного случайного значения, использованного три раза. Клиент просто отлично подключается к серверу и может получать данные. Однако данные выходят неверно. Я ясно вижу шаблон, и я подозреваю, что он может быть связан с тем, сколько байтов отправляется за один раз. Тем не менее, я думал, что буферизованный читатель будет обрабатывать чтение только в строке, если есть символ новой строки. Может кто-нибудь объяснить мне, почему числа читаются таким образом, и, может быть, укажет мне правильный путь к достижению sh того, что я хочу?

Пример вывода:

10 91 9

38 371 37

33 321 32

235 2341 234

201 2001 200

65 641 64

225 2241 224

68 671 67

116 1151 115

6 51 5

Сервер

public class Server {

    HashMap<Integer, ClientThread> clients = new HashMap<>(); // A list of clients so that they can be referenced later.

    private ServerSocket server = null; // The socket for the server
    boolean running = false; // If the server is running at all
    int responseDelta = 0; // The time between updates. Will help calculate when the server should write
                            // out all of its messages;
    int clientConnectionCount = 0; // The number of clients Connected
    int updateCounter = 1; // This is just for testing purposes

    Queue<String> incomingMessages = new LinkedBlockingQueue<>(100);
    Queue<String> outgoingMessages = new LinkedBlockingQueue<>(100);

    public Server(int port) throws IOException {
        server = new ServerSocket(port);
    }// =================================================================================================================

    public void writeMessage(String message) {
        System.out.println(message);
    }

    public void readMessages() {
        while (!incomingMessages.isEmpty()) {
            System.out.println(incomingMessages.poll());
        }
    }// =================================================================================================================

    public void sendMessages() {
        while (!outgoingMessages.isEmpty()) {
            String message = outgoingMessages.poll();
            for (int i = 0; i < clients.size(); i++) {
                clients.get(i + 1).sendMessage(message);
                ;
            }
        }
    }// =================================================================================================================

    // Starts the Server
    public void startServer() {
        System.out.println("Server was started");
        running = true;
        ConnectionThread connectionThread = new ConnectionThread();
        connectionThread.start();
        ServerThread serverThread = new ServerThread();
        serverThread.start();
    }

    /**
     * Reads and writes to a client connected through a socket
     * 
     * @author Sam
     *
     */
    private class ClientThread extends Thread {
        private Socket socket = null;
        private InputStream clientIn;
        private PrintWriter clientOut;
        BufferedReader bufferedReader;
        boolean connected;

        private ClientThread(Socket socket) throws IOException {
            this.socket = socket;
            connected = true;
            clientIn = socket.getInputStream();
            clientOut = new PrintWriter(socket.getOutputStream());
            bufferedReader = new BufferedReader(new InputStreamReader(clientIn));
        }// =============================================================================================================

        public void sendMessage(String message) {
            clientOut.write((message + "\n"));
            clientOut.flush();
        }

        @Override
        public void run() {
            try {
                while (connected && running) {
                    clientIn = socket.getInputStream();
                    String line = null;
                    line = bufferedReader.readLine();
                    if (line != null) {
                        incomingMessages.add(line);
                    }
                }
                socket.close(); // close the socket because we should be done.
            } catch (IOException e) {
                System.out.println("Turminating socket");
                connected = false;
                e.printStackTrace();
            }
        }
    }

    //Creates a thread that will listen to incoming connections
    private class ConnectionThread extends Thread {
        @Override
        public void run() {
            while (running) {
                Socket socket = null;
                try {
                    socket = server.accept(); // A client has just connected
                    ClientThread clientThread = new ClientThread(socket); // Create a new thread to read and write to
                                                                            // the socket. If we didn't it would just
                                                                            // get dropped after scope.
                    clientThread.start();
                    clients.put(++clientConnectionCount, clientThread); // Put it in the hash map so that it can be
                                                                        // referenced later.
                    System.out.println("A new client connected");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // Creates a thread that will write and read
    private class ServerThread extends Thread {
        @Override
        public void run() {
            Random rnd = new Random();
            while (running) {
                readMessages();
                int color = rnd.nextInt(254)+1;
                outgoingMessages.add(color + 1 + "\t" + color + 1 + "\t" + color);
                sendMessages();
            }
        }// =============================================================================================================
    }

}// #####################################################################################################################

Клиент

public class Client {


    boolean running = true;
    int port;
    String address;
    OutputStream clientOut;
    BufferedReader clientIn;




    public void connect(String address, int port) throws IOException {
        ServerConnectionThread sct = new ServerConnectionThread(new Socket("127.0.0.1", port));
        sct.start();

    }

    public void writeToServer(String data) {
        try {
            clientOut.write((data +"\n").getBytes());
            clientOut.flush();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }



    private class ServerConnectionThread extends Thread{

        Socket connection;

        public ServerConnectionThread(Socket socket) throws UnknownHostException, IOException {
            connection = socket;
            clientIn = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            clientOut = connection.getOutputStream();
        }

         @Override
         public void run() {
             while(running){
                 String line = null;
                 try {
                    line = clientIn.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                 if( line != null){
                    System.out.println(line);
                 }
             }

         }//=============================================================================================================
    }
}

1 Ответ

0 голосов
/ 25 января 2020

Как только вы вводите строку в выражение +, вы делаете конкатенацию строк только для оставшейся части выражения.

Первый color + 1 интерпретируется как математическое сложение, поскольку строки не имеют встречается в выражении в этой точке.

Это:

outgoingMessages.add(color + 1 + "\t" + color + 1 + "\t" + color);

фактически идентично этому:

outgoingMessages.add(
    new StringBuilder(String.valueOf(color + 1))   // mathematical addition
    .append("\t")
    .append(String.valueOf(color))
    .append(String.valueOf(1))
    .append("\t")
    .append(String.valueOf(color))
    .toString());

Решение состоит в том, чтобы выделить математическое выражение, так что это интерпретируется как математика:

outgoingMessages.add(color + 1 + "\t" + (color + 1) + "\t" + color);

Для ясности я лично заключил бы в скобки оба математических выражения:

outgoingMessages.add((color + 1) + "\t" + (color + 1) + "\t" + color);

Конечно, color - это одна переменная, так что вы печать трех чисел, которые основаны на одном значении. Переменная никоим образом не «привязана» к каким-либо предыдущим присваиваниям, которые она может добавить; переменная устанавливается только в тот момент, когда в программе встречается присвоение.

Если вы хотите три случайных числа, вам нужно выполнить три операции со случайными числами и три назначения:

int color1 = rnd.nextInt(254) + 1;
int color2 = rnd.nextInt(254) + 1;
int color3 = rnd.nextInt(254) + 1;
outgoingMessages.add((color1 + 1) + "\t" + (color2 + 1) + "\t" + color3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...