首页 文章

TCP / IP客户端:从服务器读取多个输入流的最佳方式

提问于
浏览
3

我正在创建一个Java客户端程序,它向服务器发送命令,服务器发送回确认和响应字符串 .

响应以这种方式发回客户端 - >服务器:cmd_string服务器 - >客户端:ack_msg(06)服务器 - >客户端:response_msg

当我尝试读取输入时,我只能读取只读取一个输入流的确认消息

我的客户端程序能够以某种方式读取消息(hacky方法) . 要读取输入,我必须使用Bufferedreader读取ack消息 .

  • 这个缓冲的阅读器只能读取ack_msg而不是以下的msg

  • 需要DataInputstream代码来读取响应消息 .

  • 如果我跳过第1步并且只使用Datainputstream,我将无法读取完整的消息 .

Client.java

try {
            Socket clientSocket = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);// ip,port

            System.out.println(" client Socket created .. ");

            PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);

            String ToServer = command;
            outToServer.println(ToServer);

            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//          
            // while (!in.ready()) {
            // }
            System.out.println(in.read()); // Read one line and output it


            // ===
            byte[] messageByte = new byte[1000];//assuming msg size -need to know eact msg size ?
            boolean end = false;
            String dataString = "";
            int bytesRead = 0;

            try {
                DataInputStream in1 = new DataInputStream(clientSocket.getInputStream());
//
                while (!end) {
                    bytesRead = in1.read(messageByte);
                    dataString += new String(messageByte, 0, bytesRead);
                    if (dataString.length() > 0) {
                        end = true;
                    }
                }
                System.out.println("MESSAGE: " + dataString);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // ===

            in.close();             

            clientSocket.close();
            System.out.print("connection closed");

        } catch (Exception e) {
            System.out.print("Whoops! It didn't work!\n");
            e.printStackTrace();
        }

Output

客户端套接字创建..

响应:6

消息:³CO³0³Œ

连接关闭

When I skip step 1

客户端套接字创建..

信息: -

连接关闭

如何编写从服务器读取所有输入的代码(确认消息和响应消息,它还应检查数据大小并相应地读取)?

提到How to read all of Inputstream in Server Socket JAVA

谢谢

3 回答

  • 0

    一旦发送至少1个字节,这些语句就会强制关闭流 .

    dataString += new String(messageByte, 0, bytesRead);
    if (dataString.length() > 0) {
       end = true;
    }
    

    一旦收到6的确认,连接就会关闭 . 如果忽略ack,则可以在多个分组中发送响应,在接收到第一个分组之后连接将关闭 .

    您必须能够确定确认和响应何时结束 .

    • 如果你知道ack和响应中有多少个字符,你可以像你提到的问题一样循环 . 你需要一个ack循环和一个响应循环 .

    • 如果您不知道字符数,则必须查找特殊字符,例如行尾或文件结尾,以了解ack行何时结束以及服务器响应何时结束 . 在每条消息的末尾查找特殊字符 .

    • 第三种可能性是等待一段特定的时间 . 时间到期后,继续 . 这在TCP上是不可靠的,因为数据可能丢失并重新发送 . 可能需要比分配响应更多的时间 . 我同意以下评论 . 最初,我犹豫是否在列表中添加3个 . 该选项很可能用于检测通信信道的问题 . 如果时间到期,那么客户端将放弃错误条件,它将不会继续处理,好像一切都好 .

  • 2

    您不能在同一底层套接字上同时使用BufferedReader和DataInputStream . 您将丢失BufferedReader中的数据 . 对所有内容和套接字的使用寿命使用相同的流或阅读器 . Ditto编写器和输出流 .

  • 2
    InputStream input = null;
    OutputStream output = null;
    
    Socket cs = new Socket("LocalHost", 6789);
     input = cs.getInputStream();
    output = cs.getOutputStream();
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(output));
    
    bw.write("Send your String");
    bw.flush();
    
    int bytesRead = 0;
    byte[] messageByte = new byte[1000];
    String dataString = "";
    
    bytesRead = input.read(messageByte);
    dataString = new String(messageByte, 0, bytesRead);
    

相关问题