皆さん、私はうまく拡張し、何千ものクライアントに役立つサーバープログラムを開発しています。問題は、Apache MINAがあまりにも重すぎて、私はそれを使わないことにして、代わりに自分のクライアントリスナーを書いたと感じています。私は実際にはJavaで非同期のソケット操作を行ったことはありませんでした。(C#はそれをはるかに簡単にしましたが、私はソケット読み込みの他にすべてをよく知っていたので、スレッドプールは正しく私にとっては難しいです。 Apache MINAのドキュメントを使って、どのようにしたらよいかを知ることができました。Executors.newFixedThreadPoolを使用した非同期Java NIOのヘルプ
- スレッドプールが正しく使用されていますか? Apache MINAのデフォルトのスレッドサイズはCPUコアの数+1ですが、何千ものクライアントを受け入れるためにCore 2 Duo用のスレッドスレッドプールを3つ使用する必要がありますか?
- 私は、クライアントから受信したメッセージごとにバッファを2回再割り当てすることを知っています(各メッセージは2パケット、1つのヘッダーは定数4バイト、長さはヘッダーに指定された内容パケットです)。バッファーオーバーランをチェックする固定サイズのバッファーを使用する簡単な方法はありますか?そのため、バッファーは常に同じですが、バッファーは絶えず再割り当てする必要はありませんか?
は、ここで私はリスナーを起動方法は次のとおりです。
private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1;
private ServerSocket socket;
private ExecutorService threadPool;
private int port;
public ClientListener(int port) {
this.port = port;
threadPool = Executors.newFixedThreadPool(THREADS);
}
public void init() {
try {
socket = new ServerSocket(port);
} catch (IOException ex) {
}
}
public void run() {
while (true) {
try {
ClientSession s = new ClientSession(socket.accept());
threadPool.execute(s);
} catch (IOException ex) {
}
}
}
ClientSessionの関連するコード:
private Socket socket;
private byte[] buffer;
private boolean isHeader;
public ClientSession(Socket socket) {
this.socket = socket;
this.buffer = new byte[4];
this.isHeader = true;
}
public void run() {
InputStream in;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException ex) {
return;
}
while (!socket.isClosed()) {
try {
int read = in.read(buffer);
if (read == -1)
break;
receive(read);
} catch (IOException ex) {
break;
}
}
}
private void receive(int readBytes) {
if (isHeader) {
if (readBytes >= 4) {
buffer = new byte[getPacketLength(buffer)];
isHeader = false;
} else {
System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet.");
}
} else {
if (readBytes >= buffer.length) {
processMessage(new LittleEndianByteArrayReader(decryptData(buffer)), this);
buffer = new byte[4];
isHeader = true;
} else {
System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet (needed " + buffer.length + ", received " + readBytes + ").");
}
}
}
あなたがいないここ
ClientListener cl = new ClientListener(1234);
cl.init();
new Thread(cl).start();
はClientListenerに関連するコードですgetPacketLength、processMessage、decryptのコードを知る必要があるデータ、およびクラスLittleEndianByteArrayReaderがありますが、私はこれらのメソッド/クラスの目的が明らかであることを確信しています。
あなたが例外を飲み込んでいるということです。少なくともログに記録する。 – dogbane
これはコードスニペットです。実際のコードでは、詳細なメッセージとともにjava.util.Loggerを使用してログを記録します。 –
あなたはNIOをまったく使用していませんか?そのためにセレクタが必要です。 –