Javaでのノンブロッキングソケット書き込みの提案を探しています。私のコードは、いくつかのデータをソケットに書き出すだけで、それを完全に忘れてしまいます。応答やデータが実際に消費されるタイミングは気にしません。これを行うための最良の方法は何ですか?
4 に答える
このような複雑な状況に陥った場合の最良のアイデアは、KryoNet(より複雑でより多くの機能)やPryoNet(より複雑ではなく、より少ない機能)のようなネットワークライブラリを使用することです。本当に必要な場合は、それらを分解して、それらがどのように機能するかを理解することができます。Socket
送信バッファがいっぱいの場合にのみブロックに書き込むことに注意してください。
このルートを使用しない場合、スレッド同期なしでこの単純なケースを処理するには、を使用する必要があります。これSelectors
はChannels
、バッファがいっぱいでなくても、ソケットがいつでも「書き込み可能」であるかどうかをビジーループなしで簡単に確認する方法がないためです。基本Socket
クラスのレベル通知メカニズム。スレッドでソケットを使用することもできます。そうすれば、問題なく無期限にブロックできますが、同期の問題が発生する可能性があります。
あなたが非同期I/Oの後であるように私には聞こえます。簡単な例を次に示します。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class Test
{
public static void main(String[] args)
{
final AsynchronousSocketChannel out = AsynchronousSocketChannel.open();
out.connect(new InetSocketAddress("www.google.com", 80), null,
new CompletionHandler<Void, Void>()
{
@Override
public void completed(Void result, Void attachment)
{
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.asCharBuffer().put("GET /index.html HTTP/1.1");
out.write(buffer, null, new CompletionHandler<Integer, Void>()
{
@Override
public void completed(Integer result, Void attachment)
{
// ignore the result
}
@Override
public void failed(Throwable t, Void attachment)
{
t.printStackTrace();
}
});
}
@Override
public void failed(Throwable t, Void attachment)
{
t.printStackTrace();
}
});
}
}
凝ったフレームワークは必要ありません。Java7非同期ソケットは非常に使いやすいです。
これらのイベントを投稿するスレッドを作成します。スレッドは実行されるバックグラウンドであり、データをサーバーに送信します。
Java NIO(複雑)のセレクターとチャネルを使用できます。または、ノンブロッキングI/OをサポートするApacheMINAのようなより使いやすいネットワークライブラリを試すことができます。