我的问题是关于javanio客户机-服务器消息传递,我不确定从技术上定义问题,但是:
缓冲区似乎正在缓存数据,当缓存完成后,它将所有数据一起发送,这是令人不安的逻辑:
private void sendCreate(String line,SocketChannel from)
/* A new client wishes to join the world.
This requires the client to find out about the existing
clients, and to add itself to the other clients' worlds.
Message format: create name xPosn zPosn
Store the user's name, extracted from the "create" message
*/
{ StringTokenizer st = new StringTokenizer(line);
st.nextToken(); // skip 'create' word
userName = st.nextToken();
String xPosn = st.nextToken(); // don't parse
String zPosn = st.nextToken(); // don't parse
// request details from other clients
sendBroadcastMessage( "wantDetails " + achannel.socket().getInetAddress() + " " + port,from);
// tell other clients about the new one
sendBroadcastMessage( "create " + userName + " "+xPosn+" "+zPosn,from);
} // end of sendCreate()
负责从服务器广播消息的方法:
private void sendBroadcastMessage(String mesg, SocketChannel from) {
prepWriteBuffer(mesg);
Iterator i = clients.iterator();
while (i.hasNext()) {
SocketChannel channel = (SocketChannel) i.next();
if (channel != from)
channelWrite(channel, writeBuffer);
}
}
我假设这应该发送第一条消息,即sendBroadcastmessage(“wantDetails”+achannel.socket().getInetAddress()+“”+port,from);但这不是,它似乎正在等待其他方法调用,即sendBroadcastmessage(“create”+username+“”+xposn+“”+zposn,from);然后将这两条消息作为一条消息发送,这是影响应用程序逻辑。理想情况下,它应该或应该在第一次调用sendBroadcastmessage之后发送第一条消息,然后在客户端接收到第一个调用时处理其他调用。
以下是sendBroadcastMessage()中使用的方法:
private void prepWriteBuffer(String mesg) {
// fills the buffer from the given string
// and prepares it for a channel write
writeBuffer.clear();
writeBuffer.put(mesg.getBytes());
writeBuffer.putChar('\n');
writeBuffer.flip();
}
private void channelWrite(SocketChannel channel, ByteBuffer writeBuffer) {
long nbytes = 0;
long toWrite = writeBuffer.remaining();
// loop on the channel.write() call since it will not necessarily
// write all bytes in one shot
try {
nbytes += channel.write(writeBuffer);
} catch (ClosedChannelException cce) {
cce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// get ready for another write if needed
writeBuffer.rewind();
}
请提出一些解决方案。
谢谢,
吉比拉拉
编辑:
这个呢,我从一些聊天应用程序得到了这个补丁:
private void prepWriteBuffer(String mesg) {
// fills the buffer from the given string
// and prepares it for a channel write
writeBuffer.clear();
writeBuffer.put(mesg.getBytes());
writeBuffer.putChar('\n');
writeBuffer.flip();
}
// called needs to remove the channel if it fails, otherwise it will fail forever.
private void channelWrite(SocketChannel channel, ByteBuffer writeBuffer) {
long nbytes = 0;
long toWrite = writeBuffer.remaining();
// loop on the channel.write() call since it will not necessarily
// write all bytes in one shot
try {
while (nbytes != toWrite) {
nbytes += channel.write(writeBuffer);
try {
Thread.sleep(CHANNEL_WRITE_SLEEP);
} catch (InterruptedException e) {
}
}
} catch (ClosedChannelException cce) {
} catch (Exception e) {
}
// get ready for another write if needed
writeBuffer.rewind();
}