Моя проблема связана с передачей сообщений клиентскому серверу 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 () + ""+ порт, с);но это не так, кажется, что он ожидает вызова другого метода, т.е. 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();
}
, пожалуйста, предложите какое-нибудь решение.
спасибо,
jibby lala
Редактировать: как насчет этого, я получил этот патч из какого-то приложения чата:
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();
}