有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

sockets Java客户端从服务器读取不正确的整数

该计划被认为是相对直接的。其目标是让服务器定期向连接到它的所有客户端发送rgb值(255255)。在下面的代码中,我将其简化为一个随机值,使用了三次。客户端与服务器连接良好,能够接收数据。然而,数据出来的时候并不正确。我可以清楚地看到一个模式,我怀疑它可能与一次发送多少字节有关。然而,我认为缓冲读取器只会在有新行字符的情况下处理一行中的读取。有人能给我解释一下为什么这些数字是以这种方式解读的吗?也许有人能给我指出实现我想要的目标的正确方法吗

输出示例:

10919

38 371 37

33 321 32

235 2341234

201 2001 200

65 641 64

225 2241 224

6867167

116 1151 115

6515

服务器

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) 个答案

  1. # 1 楼答案

    将字符串引入+表达式后,只需对表达式的其余部分执行字符串连接

    第一个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);