【问题标题】:Cannot extract correct information from message received through SocketChannel无法从通过 SocketChannel 接收的消息中提取正确的信息
【发布时间】:2013-04-11 02:36:57
【问题描述】:

我正在发送一个已使用 DataOutput 流转换为字节的字符串

// creates a client socket which connects to the first successor's server.
Socket clientSocket = new Socket(host, succ1_port);

// send the output_string to the first successor.
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(output_string);

然后通过 SocketChannel 接收它们:

// accept connection
SocketChannel connectionSocket = tcpserver.accept(); // tcpserver is a ServerSocketChannel

ByteBuffer buf = ByteBuffer.allocate(48);

// store and print no. of bytes read
int bytes_read = connectionSocket.read(buf);
System.out.println("bytes read = " +bytes_read);
String from_client_string = new String(buf.array(), Charset.forName("UTF-8"));

收到的消息始终采用“XXXX XXX”格式,其中 X 是 0-9 之间的任何数字。

然后我尝试将这些消息分成两部分:

Pattern p = Pattern.compile("([0-9]{4}) ([0-9]{3})"); 
Matcher m = p.matcher(from_client_string);

if (m.matches()){   
  int filename = Integer.parseInt(m.group(1));
  int hash = Integer.parseInt(m.group(2));
  System.out.println("filename = " +filename);
  System.out.println("hash = " +hash);
else
  System.out.println("no match");   

问题是,有时当我打印出从字节缓冲区转换的字符串时,它的值会发生变化......通常它是正确的,例如“1234 210”,但在其他情况下它可能会剪切一个数字并显示“1234 21” .但是,即使它是正确的,我也没有得到匹配? 我还发现正在读取的字节数总是在变化...

有人知道这里的问题是什么吗?

感谢您的帮助。

【问题讨论】:

    标签: java tcp bytebuffer socketchannel


    【解决方案1】:

    您应该循环读取套接字,直到它关闭。如果没有可用的字节,则读取将阻塞,因此请确保您正在关闭另一端的连接。

    所以在客户端

    // creates a client socket which connects to the first successor's server.
    Socket clientSocket = new Socket(host, succ1_port);
    
    // send the output_string to the first successor.
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    outToServer.writeBytes(output_string);
    outToServer.close();
    clientSocket.close();
    

    在服务器端:

    // accept connection
    SocketChannel connectionSocket = tcpserver.accept(); // tcpserver is a ServerSocketChannel
    
    ByteBuffer buf = ByteBuffer.allocate(48);
    
    // store and print no. of bytes read
    String result="";
    while(connectionSocket.isOpen()){
      int bytes_read = connectionSocket.read(buf);
      System.out.println("bytes read = " +bytes_read);
      String from_client_string = new String(buf.array(),0,bytes_read Charset.forName("UTF-8"));
      reulst+= from_client_string;
    

    } }

    【讨论】:

    • 您好 user2242863,谢谢。我做了你建议的改变,它似乎部分工作。但是,连接永远不会关闭,因此它会继续打印出“bytes read = -1”。如果我关闭服务器端的连接,我会得到一次正确的答案,然后我得到的结果与 OP 中的结果相似。接受 TCP 连接的服务器是 Selector 的一部分,如果这有什么不同?
    【解决方案2】:

    当您使用 ByteBuffer 读取时,您会得到可用的字节数,这可能不是您写入的所有字节。 DataInputStream.readUTF() 所做的是等待解码长度所需的字节数(16 位无符号值)。

    我建议你使用DataOutputStream.writeUTF(String)String DataInputStream.readUTF()。我建议你也考虑使用缓冲。

    【讨论】:

      【解决方案3】:

      谢谢彼得!你的建议似乎奏效了:)我会投票给你,但我没有足够的声誉。

      发送数据:

      // creates a client socket which connects to the first successor's server.
      Socket clientSocket = new Socket(host, succ1_port);
      
      // send the output_string to the first successor.
      DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
      outToServer.writeUTF(output_string);
      
      outToServer.close();    
      clientSocket.close();
      

      服务器端(接收数据)

      // accept connection
      SocketChannel connectionSocket = tcpserver.accept(); // tcpserver is a ServerSocketChannel
      
      DataInputStream inToServer = new DataInputStream(connectionSocket.socket().getInputStream());
      String from_client_string = inToServer.readUTF(); 
      

      模式匹配的东西与 OP 中的相同...除了现在它实际上似乎可以工作 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多