Java SocketChannel读取长度未知的消息
从套接字读取1024字节的数据。在这种情况下,所有消息都合并在一起,最后一条消息不会完全出现。如何将数据读入消息分隔符“|”之前的缓冲区?我希望单独接收每条消息。取决于协议,但如果协议基于消息分隔符字符,您唯一的选择是在不阻塞的情况下尽可能多地读取,然后扫描您读取的内容以找到分隔符。您需要在一个循环中执行此操作,直到连接关闭(或者直到您的一方决定关闭连接)Java SocketChannel读取长度未知的消息,java,messages,socketchannel,Java,Messages,Socketchannel,从套接字读取1024字节的数据。在这种情况下,所有消息都合并在一起,最后一条消息不会完全出现。如何将数据读入消息分隔符“|”之前的缓冲区?我希望单独接收每条消息。取决于协议,但如果协议基于消息分隔符字符,您唯一的选择是在不阻塞的情况下尽可能多地读取,然后扫描您读取的内容以找到分隔符。您需要在一个循环中执行此操作,直到连接关闭(或者直到您的一方决定关闭连接) 当然,您可以一次读取多条消息,甚至可以读取部分消息,因此您必须确保充分处理这些情况。TCP中没有消息。它是一个字节流API。如果您想要消息,
当然,您可以一次读取多条消息,甚至可以读取部分消息,因此您必须确保充分处理这些情况。TCP中没有消息。它是一个字节流API。如果您想要消息,您必须通过分隔符、STX/ETX对、字长前缀、自描述协议等自己实现它们。套接字API为您实现这一点。因为它已经在一个缓冲区中。这里是一个很好的读取。谈论你的问题。该库是针对obj-c的,但本文是关于tcp/udp的常见缺陷,因此其适用性不幸的是,这种方法不适合Metat,这很遗憾,因为没有其他方法会有显著的不同。如果协议不同,例如,如果每条消息都以包含消息长度的固定大小的报头开头,则会出现错误。
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int numRead = -1;
try {
numRead = channel.read(buffer);
System.out.println("numRead: " + numRead);
}
catch (IOException e) { e.printStackTrace();}
if (numRead == -1) {
this.dataMap.remove(channel);
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
System.out.println("Connection closed by client: " + remoteAddr);
channel.close();
key.cancel();
return;
}
System.out.println("Got: " + new String(buffer.array(), "windows-1251"));