私の問題は、JAVANIOクライアントサーバーのメッセージの受け渡しに関するものですが、技術的に問題を定義するのは不明ですが、 バッファがデータをキャッシュしているようです。ロジックを乱されます。サーバーからのメッセージを放送する責任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()
方法:これは最初のメッセージすなわちsendBroadcastMessage( "wantDetails" + achannel.soを送るべきであると仮定し
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);
}
}
はイムcket()。getInetAddress()+ "" +ポート、from);これは、他のメソッド呼び出し、つまりsendBroadcastMessage( "create" + userName + "" + xPosn + "" + zPosn)を待っているようで、両方のメッセージをアプリケーションロジックに影響する1つのメッセージとして送信しているようです。理想的には、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();
}
:
これらはsendBroadcastMessageに使用されている方法()です。
おかげで、
jibbyのララ
編集: 何これについては、私はいくつかのチャットアプリからこのパッチを得た:
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();
}
回答ありがとうございますが、これはこれらのメッセージの間に4つの追加文字を挿入し、それらを連結して送信しています。 –
が正しい。受信者へのその方法は、4バイトを読み取って長さを決定し、メッセージの長さを事前に知ることができる。 –
純粋なテキスト形式が必要な場合は、それを行うことができますが、NIOでメッセージの境界を見つけるためにそれをデコードするのは難しいです。 –