Java - 发送到OustputStream的两个字符串之间的差异

时间:2016-05-13 18:52:27

标签: java sockets client-server

  • 我将2个String值从Client.java发送到OutputStream中,如下所示:

    outputStream.write(username.getText().getBytes());
    outputStream.write(password.getText().getBytes());
    
  • 在Server.java中,当我读取inputStream时,我试图将每个值分开:

    inputStream = s.getInputStream(); byte[]username = new byte[20]; inputStream.read(username); String user = new String(username); System.out.println("username = "+user);

我逻辑地得到:usernamepassword作为控制台输出。 我想做的是:

     String usr = new String(user);
     String pass = new String(password);

有没有比在outputStream String中添加分隔符更好的方法呢?

2 个答案:

答案 0 :(得分:2)

您需要分隔两个字符串值,以便读者知道一个字符串的结束位置和下一个字符串的开头。该分隔符的实际内容由您自行决定。

  1. 在写出实际字节之前,您可以使用固定宽度的整数写出字符串的字节长度。然后,读者可以先读取长度,然后再读取指定的字节数:

    DataOutputStream dos = new DataOutputStream(outputStream);
    byte[] bytes;
    int len;
    
    bytes = username.getText().getBytes(StandardCharsets.UTF_8);
    len = bytes.length;
    dos.writeInt(len);
    dos.write(bytes, 0, len);
    
    bytes = password.getText().getBytes(StandardCharsets.UTF_8);
    len = bytes.length;
    dos.writeInt(len);
    dos.write(bytes, 0, len);
    

    inputStream = s.getInputStream();
    DataInputStream dis = new DataInputStream(inputStream);
    byte[] bytes;
    int len;
    
    len = dis.readInt();
    bytes = new byte[len];
    dis.readFully(bytes);
    String username = new String(bytes, StandardCharsets.UTF_8);
    
    len = dis.readInt();
    bytes = new byte[len];
    dis.readFully(bytes);
    String password = new String(bytes, StandardCharsets.UTF_8);
    

    或者,DataOutputStreamDataInputStream可以直接写入/读取String值,在内部为您处理上述逻辑(使用short代替int } for length value):

    DataOutputStream dos = new DataOutputStream(outputStream);
    dos.writeUTF(username.getText());
    dos.writeUTF(password.getText());
    

    inputStream = s.getInputStream();
    DataInputStream dis = new DataInputStream(inputStream);
    
    String username = dis.readUTF();
    String password = dis.readUTF();
    
  2. 您可以写出一个永远不会出现在字符串值本身中的唯一字符序列,例如换行符或控制字符(甚至是空终止符)。然后,读者可以读取字节,直到遇到该序列:

    OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); 
    String s;
    
    s = username.getText();
    writer.write(s, 0, s.length());
    writer.write(10);
    
    s = password.getText();
    writer.write(s, 0, s.length());
    writer.write(10);
    

    inputStream = s.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    
    String username = reader.readLine();
    String password = reader.readLine();
    

    可替换地:

    OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); 
    String s;
    
    s = username.getText();
    writer.write(s, 0, s.length());
    writer.write(0);
    
    s = password.getText();
    writer.write(s, 0, s.length());
    writer.write(0);
    

    inputStream = s.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    StringBuilder sb = new StringBuilder();
    int ch;
    
    do
    {
        ch = reader.read();
        if (ch <= 0) break;
        sb.append((char)ch);
    }
    while (true);
    String username = sb.toString();
    
    sb.setLength(0);
    do
    {
        ch = reader.read();
        if (ch <= 0) break;
        sb.append((char)ch);
    }
    while (true);
    String password = sb.toString();
    

答案 1 :(得分:0)

我会选择DataOutputStream进行写作,DataInputStream进行阅读。有了这些,你可以在每个String之前写一个整数值来知道文本的长度,如下所示:

DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeInt(username.getText().length());
dos.write(username.getText().getBytes());
dos.writeInt(password.getText().length());
dos.write(password.getText().getBytes());

然后,在服务器端:

DataInputStream dis = new DataInputStream(inputStream);
int length = 0; // will be used to store the length of each text

length = bytesRead = dis.readInt(); // Read the length of the first text
byte[] usernameBuffer = new byte[length];
dis.read(usernameBuffer);
String username = new String(usernameBuffer);

// Now reading the other text
length = dis.readInt(); // Read the length of the second text
byte[] passwordBuffer = new byte[length];
dis.read(passwordBuffer);
String password = new String(passwordBuffer);