gpt4 book ai didi

Java NIO - 使用 SocketChannel 接收数据的问题

转载 作者:行者123 更新时间:2023-12-01 15:52:38 25 4
gpt4 key购买 nike


我正在使用 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){

不保证阅读您的整个消息,它可能什么也没读,也可能读到部分消息或多条消息。

套接字是字节流,如果您想读取数据包(就像您所做的那样),您需要对流进行打包。

一种方法是在数据包前面添加长度,并确保在尝试处理之前读取整个数据包。

另一种方法是以一种具有唯一终止符的方式写入数据包,您可以读取该终止符,直到获得终止符。

关于Java NIO - 使用 SocketChannel 接收数据的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5710031/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com