如何解决Java NIO-使用SocketChannel接收数据的问题
| 我正在使用Java NIO编写简单的即时通讯程序。客户端不会收到已登录联系人的消息,这是很好的工作。 这是主要的服务器处理方法:public void process() throws IOException,ClassNotFoundException{
while (true){
selector.select();
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext()){
SelectionKey key = (SelectionKey)it.next();
it.remove();
if (key.isAcceptable()){
/*configuring incoming channel to be non-blocking
and adding it to the clients set*/
}
if (key.isReadable()) {
SocketChannel client = (SocketChannel)key.channel();
/*Message class contains its type,source user name and data.
getMessage() method reads message from SocketChannel*/
Message m = getMessage(client);
switch (m.getType()) {
case LOGIN_REQUESTED:
/*Accept or reject the client log in name
in case of accepting add user with its status
to Map users*/
break;
case CONTACTS_REQUESTED:
/*Here is the problem,client gets only one message
sendMessage() writes the buffer with serialized
message to clients channels*/
for (String name : users.keySet()) {
sendMessage(client,MessageType.CONTACTS_REQUESTED,name,users.get(name).toString());
}
break;
//Other messages are processing
}
}
}
}
}
客户端方法,用于处理传入消息:
private void processIncomingMessages()
throws IOException,ClassNotFoundException {
ByteArrayInputStream bais;
ObjectInputStream ois;
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
while (true){
selector.select();
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext()){
SelectionKey key = (SelectionKey)it.next();
it.remove();
if (key.isReadable()){
SocketChannel sc = (SocketChannel)key.channel();
buffer.clear();
if (sc.read(buffer) != -1){
buffer.flip();
bais = new ByteArrayInputStream(buffer.array());
ois = new ObjectInputStream(bais);
Message m = (Message)ois.readobject();
/*My castom event serves to notify GUI to update
its contact list. In case of sending CONTACTS_REQUESTED
messages,it gets only one (first?) of them*/
fireNetworkEvent(m);
}
}
}
}
}
单独发送的其他消息不会出现任何问题。
如有任何疑问,请询问。任何帮助将不胜感激解决方法
我的猜测是在客户...
if (sc.read(buffer) != -1){
不能保证阅读完整的消息,它可能什么也不读取,其中的一些消息或多条消息。
套接字是字节流,如果您想读取数据包(如您所做的那样),则需要对流进行打包。
一种方法是在数据包长度之前添加前缀,并确保在尝试处理之前先阅读了整个数据包。
另一种方法是使用具有唯一终止符的方式写入数据包,直到读取终止符为止。版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。