Javaにおけるソケットプログラミング:チュートリアル

このチュートリアルは、java I/Oの基本機能を示す簡単なクライアント-サーバーの例から始まり、javaにおけるソケットプログラミングの概要です。java.ioパッケージと、Java1.4で導入されたノンブロッキングI/O(java.nio)Apiの両方について紹介します。 最後に、NioでJava7以降から実装されたJavaネットワーキングを示す例を見ることができます。2.,

ソケットプログラミングは、互いに通信する二つのシステムに集約されます。 一般に、ネットワーク通信には、Transport Control Protocol(TCP)とUser Datagram Protocol(UDP)の二つのフレーバーがあります。 TCPとUDPは異なる目的で使用され、どちらも一意の制約があります。

  • TCPは、クライアントがサーバと通信するための二つのシステムに接続することを可能にする比較的単純で信頼性の高いプロトコルです。 TCPでは、各エンティティはその通信ペイロードが受信されたことを認識します。,
  • UDPはコネクションレスプロトコルであり、メディアストリーミングなど、すべてのパケットが宛先に到着する必要がないシナリオに適しています。

TCPとUDPの違いを理解するために、お気に入りのウェブサイトからビデオをストリーミングしていて、フレームを落とした場合にどうなるか するとともに、顧客ダ映画を受け、フレームやお好みの動画アップグレードどん? ビデオストリーミングプロトコ, TCPは配信を保証するため、HTTP、FTP、SMTP、POP3などに選択されるプロトコルです。

このチュートリアルでは、javaでのソケットプログラミングについて紹介します。 オリジナルのJava I/Oフレームワークの機能を示す一連のクライアント-サーバーの例を示し、徐々にNIOで導入された機能を使用するように進めます。2.

古い学校のJavaソケット

NIOより前の実装では、Java TCPクライアントソケットコードはjava.net.Socketクラスによって処理されます。, 次のコードは、サーバーへの接続を開きます。

Socket socket = new Socket( server, port );

socketインスタンスがサーバーに接続されると、サーバーへの入出力ストリームの取得を開始できます。 入力ストリームを読み込むために使用します。からのデータはサーバが出力ストリームを書き込むのに使用されるデータはサーバー通信を行います。, 次のメソッドを実行して入力ストリームと出力ストリームを取得できます。

InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();

これらは通常のストリームであり、ファイルの読み取りと書き込みに使用するのと同じストリームであるため、ユースケースに最適な形式に変換することができます。 たとえば、OutputStreamPrintStreamラップして、println()ようなメソッドでテキストを簡単に書くことができます。, 別の例として、InputStreamBufferedReaderInputStreamReaderようなメソッドでテキストを簡単に読み取るためにreadLine()

“Javaでのソケットプログラミング:チュートリアル”のソースコードをダウンロードします。”JavaWorldのためにスティーブン*ヘインズによって作成されました

Javaソケットクライアントの例

HTTPサーバーに対してHTTP GETを実行する短い例を見てみましょう。, HTTPはこの例で許可されているよりも洗練されていますが、サーバーからリソースを要求すると、サーバーが応答を返してストリームを閉じるという最も単純なケース この場合、次の手順が必要です。

  1. ポート80でリッスンしているwebサーバーへのソケットを作成します。
  2. PrintStreamをサーバーに取得し、リクエストGET PATH HTTP/1.0を送信します。PATHはサーバー上で要求されたリソースです。, たとえば、webサイトのルートを開く場合、パスは/になります。サーバーにInputStreamを取得し、それをBufferedReaderでラップし、レスポンスを行ごとに読み取ります。

リスト1に、この例のソース-コードを示します。

リスト1. SimpleSocketClientExample。java

リスト1には、接続するサーバー(ポート80でサーバーに接続していると仮定します)と取得するリソースの二つのコマンドライン引数を受け入れます。, サーバーを指し、明示的にポートを指定するSocketを作成します80。 次に、コマンドを実行します。

GET PATH HTTP/1.0

例えば、

GET / HTTP/1.0

何が起こったのですか?

などのwebサーバーからwebページを取得すると、HTTPクライアントはDNSサーバーを使用してサーバーのアドレスを検索します。com権限のあるドメインネームサーバーがドメインのトップレベルドメインサーバーに要求することから始まります。, 次に、のIPアドレス(またはアドレス)をドメインネームサーバーに要求します。 次に、ポート80でそのサーバーへのソケットを開きます。 (または、別のポートを定義する場合は、:8080のように、コロンの後にポート番号を追加することで、それを行うことができます。 最後に、HTTPクライアントは、GETPOSTPUTDELETEHEADOPTI/ONSなどの指定されたHTTPメソッドを実行します。 各メソッドには独自の構文があります。, 上記のコードsnipsに示されているように、GETメソッドには、HTTP/version numberが続くパスと空の行が必要です。 HTTPヘッダーを追加したい場合は、新しい行を入力する前にそうすることができます。

リスト1では、OutputStreamを取得し、PrintStreamでラップして、テキストベースのコマンドをより簡単に実行できるようにしました。, 私たちのコードはInputStreamを取得し、それをInputStreamReaderでラップし、それをReaderに変換し、それをBufferedReaderPrintStreamを使用してGETメソッドを実行し、次にBufferedReaderを使用して、null応答を受け取るまで、ソケットが閉じられていたことを示す応答を行ごとに読み取ります。,

このクラスを実行し、次の引数を渡します。

java com.geekcap.javaworld.simplesocketclient.SimpleSocketClientExample www.javaworld.com /

以下のような出力が表示されます。

この出力はJavaWorldのwebサイトにテストページを表示します。

この出力は、JavaWorldのwebサイトにあるテストページを表示します。

この出力は、JavaWorld それはHTTPバージョン1.1を話し、応答は200 OKであることを返しました。

Javaソケットサーバーの例

クライアント側について説明しましたが、幸いなことに、サーバー側の通信の側面も同じように簡単です。, 単純な観点からは、プロセスは次のとおりです。

  1. リッスンするポートを指定してServerSocketを作成します。
  2. ServerSocketaccept()メソッドを呼び出して、クライアント接続用に構成されたポートをリッスンします。
  3. クライアントがサーバーに接続すると、accept()メソッドはSocketを返し、サーバーがクライアントと通信できます。, これは、クライアントに使用したSocketクラスと同じであるため、プロセスは同じです。InputStreamクライアントから読み取り、OutputStreamクライアントに書き込みます。サーバーをスケーラブルにする必要がある場合は、Socketを別のスレッドに渡して処理し、サーバーが追加の接続をリッスンし続けることがで
  4. 別の接続をリッスンするには、ServerSocketaccept()メソッドを再度呼び出します。,

すぐにわかるように、NIOのこのシナリオの処理は少し異なります。, ただし、今のところ、リッスンするポートを渡すことでServerSocketを直接作成できます(次のセクションではServerSocketFactoryについて詳しく)。

ServerSocket serverSocket = new ServerSocket( port );

そして、accept()メソッド:

Socket socket = serverSocket.accept();// Handle the connection ...

javaソケットを使用したマルチスレッド-プログラミング

以下のリスト2では、これまでのすべてのサーバー-コードを、スレッドを使用して複数のリクエストを処理する少し堅牢な例にまとめました。, 表示されるサーバーはエコーサーバーであり、受信したメッセージをエコーバックします。

リスト2の例は複雑ではありませんが、NIOの次のセクションで起こることのいくつかを予期しています。 複数の同時リクエストを処理できるサーバーを構築するために記述する必要があるスレッドコードの量に特に注意してください。

リスト2. シンプルソケットサーバー。java

リスト2では、新しいSimpleSocketServerインスタンスを作成し、サーバーを起動します。, これは、SimpleSocketServerThreadを拡張して、ブロッキングを処理する新しいスレッドを作成するために必要ですaccept()read()メソッド run()メソッドは、クライアント要求を受け入れ、要求を処理するためのRequestHandlerスレッドを作成するループ内にあります。 これは比較的簡単なコードでも、フレプログラミング,

RequestHandlerは、リスト1のコードと同じようにクライアント通信を処理します。OutputStreamPrintStreamでラップして、簡単な書き込みを容易にし、同様にInputStreamを読みやすいように。 サーバーが行く限り、クライアントから行を読み取り、それらをクライアントにエコーバックします。 クライアントが空の行を送信すると、会話は終わり、RequestHandlerはソケットを閉じます。

NIOおよびNIO。,2

多くのアプリケーションでは、先ほど調べたjavaソケットプログラミングの基本モデルで十分です。 より集中的なI/Oまたは非同期入出力を含むアプリケーションでは、Java NIOおよびNIOで導入されたノンブロッキングApiに精通している必要があります。2.

JDK1.4NIOパッケージは、次の主要な機能を提供します。

  • チャネルは、あるNIOバッファーから別のNIOバッファーへの一括転送をサポートするように設計されています。
  • バッファは、単純な操作のセットによってインターフェイスされる連続したメモリブロックを表します。,
  • ノンブロッキング入出力は、ファイルやソケットなどの一般的なI/Oソースにチャネルを公開するクラスのセットです。

NIOでプログラミングするときは、宛先へのチャネルを開き、宛先からデータをバッファに読み込み、データをバッファに書き込み、宛先に送信します。,

  1. バッファにデータを書き込む
  2. バッファのflip()メソッドを呼び出して読み込む
  3. バッファからデータを読み込む
  4. バッファのclear()またはバッファのclear()またはcompact()より多くのデータを受信するためにそれを準備する方法

データがバッファに書き込まれると、バッファはそれに書き込まれたデータの量, 位置:書き込みモードでは、最初の位置は0で、バッファ内に書き込まれている現在の位置を保持します。

  • 読み込みモードに入れるためにバッファを反転した後、位置を0にリセットし、読み込まれているバッファ内の現在の位置を保持します。
  • Capacity:バッファの固定サイズ
  • Limit:書き込みモードでは、制限はバッファに書き込むことができるデータの量を定義します。この制限は、バッファから読み取ることができるデータの量を定義します。,
  • Java I/Oデモ:Nioを使用したエコーサーバー。2

    NIO.2はJDK7で導入され、JavaのノンブロッキングI/Oライブラリを拡張して、パッケージやjava.nio.file.Pathクラスなどのファイルシステムタスクのサポートを追加し、新しいファイルシステムAPIを公開します。 その背景を念頭に置いて、NIOを使用して新しいEchoサーバーを作成しましょう。2のAsynchronousServerSocketChannel

    AsynchronousServerSocketChannelは、ストリーム指向のリッスンソケット用の非ブロッキング非同期チャネルを提供します。, これを使用するには、まず静的なopen()メソッドを実行し、次にbind()を特定のポートに実行します。 次に、accept()メソッドを実行し、CompletionHandlerインターフェイスを実装するクラスを渡します。 ほとんどの場合、そのハンドラーは匿名の内部クラスとして作成されています。

    リスト3に、新しい非同期エコー-サーバーのソース-コードを示します。

    リスト3. シンプルソケットサーバー。,java

    リスト3では、まず新しいAsynchronousServerSocketChannelを作成し、それをポート5000にバインドします。

     final AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));

    このAsynchronousServerSocketChannelから、accept()を呼び出して、接続のリッスンを開始し、カスタム

    id=”351b770bbb”>

    インスタンス。 私たちが呼び出すときaccept()、それはすぐに戻ります。, この例は、リスト1のServerSocketクラスとは異なりますが、accept()メソッドはクライアントが接続するまでブロックされますが、AsynchronousServerSocketChannelaccept()メソッドはこれを処理します。

    完了ハンドラ

    次の責任は、CompletionHandlerクラスを作成し、completed()およびfailed()メソッドの実装を提供することです。, completed()メソッドは、AsynchronousServerSocketChannelがクライアントからの接続を受信し、クライアントへのAsynchronousSocketChannelを含むときに呼び出されます。 completed()メソッドは、まずAsynchronousServerSocketChannelからの接続を受け入れ、クライアントとの通信を開始します。 こんにちは、”Hello”メッセージを書き出すことです。文字列を作成し、バイト配列に変換してから、ByteBuffer.wrap()に渡して、ByteBuffer。。。。。。。。。。。。。。, その後、ByteBufferAsynchronousSocketChannelwrite()メソッドを渡すことができます。

    クライアントから読み取るために、新しいByteBufferを作成しますallocate(4096)(4Kバッファを作成します)を呼び出し、次にAsynchronousSocketChannelread()メソッドを呼び出します。 read()は、Future<Integer>を返します。get()を呼び出して、クライアントから読み取ったバイト数を取得します。, この例では、get()20秒のタイムアウト値を渡します:20秒で応答が得られない場合、get()メソッドはTimeoutExceptionをスローします。 このエコーサーバーのルールは、20秒の沈黙を観察すると、会話を終了するということです。

    次に、クライアントから受け取った最後のバイトの位置になるバッファの位置を確認します。 クライアントが空の行を送信した場合、キャリッジリターンと改行の二つのバイトを受け取ります。, このチェックは、クライアントが空白行を送信した場合、クライアントが会話を終了したことを示す指標としてそれを取ることを保証します。 意味のあるデータがある場合は、ByteBufferflip()メソッドを呼び出して読み取りの準備をします。 クライアントから読み取ったバイト数を保持する一時バイト配列を作成し、ByteBufferget()を呼び出してそのバイト 最後に、新しいStringインスタンスを作成して、バイト配列を文字列に変換します。, 文字列をバイト配列に変換し、それをByteBuffer.wrap()メソッドに渡し、AsynchronousSocketChannelwrite()メソッドを呼び出します。 ここで、clear()ByteBufferこれは、positionをゼロに再配置し、ByteBufferを書き込みモードにしてから、クライアントから次の行を読み取ります。,

    注意すべきことは、サーバーを作成するmain()メソッドも、アプリケーションの実行を維持するために60秒のタイマーを設定することだけです。 AsynchronousSocketChannelaccept()メソッドはすぐに返されるため、Thread.sleep()がない場合、アプリケーションはすぐに停止します。,

    これをテストするには、サーバーを起動し、telnetクライアントを使用して接続します。

    telnet localhost 5000

    いくつかの文字列をサーバーに送信し、それらがエコーバックされていることを確認し、空の行を送信して会話を終了します。

    結論として

    この記事では、javaを使用したソケットプログラミングに対する二つのアプローチを紹介しました。Java1.0で導入された伝統的なアプローチと、新しいノンブロッキングNIOとNIOで導入されたものです。2つのアプローチは、それぞれJava1.4とJava7で導入されました。, 基本的なJava I/Oの有用性と、ノンブロッキングI/OがJavaソケットプログラミングモデルを改善するいくつかのシナリオの両方を示す、Java socket clientとJava socket server 非ブロッキングI/O、プログラムすることが可能ですJavaネットワークへの応用を扱う複数の同時接続せずに複数のスレッドます。 また、NIOとNIOに組み込まれている新しいサーバーのスケーラビリティを活用することもできます。2.

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です