TCP / IP客户端:从服务器

时间:2016-01-17 16:11:32

标签: java sockets tcp client

我正在创建一个java Client程序,它向服务器发送命令,服务器发回一个确认和一个响应字符串。

  

以这种方式发送回复

     

客户 - > server:cmd_string

     

服务器 - >客户:ack_msg(06)

     

服务器 - >客户:response_msg

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

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

  1. 这个缓冲的阅读器只能读取ack_msg而不是以下msg
  2. 需要DataInputstream代码来读取响应消息。
  3. 如果我跳过第1步并使用Datainputstream,我将无法阅读完整的消息。
  4. 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();
            }
    

    输出

    客户端套接字创建..

    响应:6

    消息:³CO³0³Œ

    连接关闭

    当我跳过第1步

    客户端套接字创建..

    消息: -

    连接关闭

      

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

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

    由于

3 个答案:

答案 0 :(得分:2)

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

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

一旦收到6的ack,连接就会关闭。如果忽略ack,则响应可能以多个数据包发送,连接将在收到第一个数据包后关闭。

您必须能够确定ack和响应何时结束。

  1. 如果你知道ack和响应中有多少个字符,你可以像你提到的问题一样循环。你需要一个ack循环和一个响应循环。
  2. 如果你不知道的数量 字符,然后你将不得不寻找特殊字符,如 在行结束或结束时知道ack行何时结束以及何时结束 服务器响应结束。在每条消息的末尾寻找一个特殊字符。
  3. 第三种可能性是等待a 具体的时间。时间到期后,继续。这在TCP上是不可靠的,因为数据可能丢失并重新发送。可能需要花费更多时间来分配回复。我同意以下评论。最初,我犹豫在列表中添加3。该选项很可能用于检测通信信道的问题。如果时间到期,那么客户端会放弃一个错误条件,它不会继续处理好像一切都好。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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