ネットワークアプリケーションは、クライアントとサーバーの2つの部分に分割され、ソケットクラスはクライアント通信の処理を担当するJavaクラスです。このクラスを通じて、指定されたIPまたはドメイン名でサーバーに接続でき、サーバーで互いにデータを送信および受信できます。ソケットクラスの使用については、この記事と、ソケットクラスの基本、さまざまな接続方法、取得メソッド、接続中のタイムアウト、ネットワーク接続の閉鎖など、後にいくつかの記事で詳しく説明します。
この記事では、ソケットクラスを使用する基本的な手順と方法について説明します。一般に、ネットワーククライアントプログラムは、サービスプログラムに接続するときに、次の3つのステップを実行する必要があります。
1.サーバーに接続します
クライアントは2つの方法でサーバーに接続できます。1つはIPを介してサーバーに接続することであり、もう1つはドメイン名を介してサーバーに接続することです。
実際、これらの2つの方法は本質的に1つの方法です。基礎となるクライアントでは、それらはすべてIPを介してサーバーに接続しますが、2つの方法には特定の違いがあります。サーバープログラムがIPを介して接続されている場合、クライアントは単にIPに従って接続するだけです。サーバーがドメイン名を介して接続されている場合、クライアントはDNSを介してドメイン名をIPに解決し、このIPに従って接続する必要があります。
ドメイン名を使用してサーバーに接続する場合、多くのプログラミング言語または開発ツール(C/C ++、Delphiなど)では、最初にドメイン名をIPに解決し、次にIPを介して接続する必要があります。 Javaでは、ドメイン名の解像度関数がソケットクラスに含まれています。したがって、IPを使用するなど、ドメイン名を使用する必要があります。
ソケットクラスを介してサーバープログラムに接続する最も一般的な方法は、ソケットクラスコンストラクターを介してパラメーターとしてソケットクラスにパラメーターとして渡すことです。ソケットクラスのコンストラクターには、多くの過負荷型フォームがあります。このセクションでは、最も一般的に使用されるフォームの1つのみについて説明します:パブリックソケット(String Host、Int Port)。このコンストラクターの定義から、IPまたはドメイン名とポート番号をコンストラクターに直接渡すだけです。次のコードは、サーバープログラムに接続する例プログラムです。
パッケージmysocket; java.net。*; public class myConnection {public static void main(string [] args){try {if(args.length> 0){socket socket = new Socket(args [0]、80); system.out.println(args [0] + "接続に正常に!"); } else system.out.println( "IPまたはドメイン名を指定してください!"); } catch(Exception E){System.err.println( "エラーメッセージ:" + e.getMessage()); }}}上記では、IPまたはドメイン名がコマンドラインパラメーターを介してプログラムに渡され、コマンドラインパラメーターを介して指定されたIPまたはドメイン名の80ポートがソケットソケット= new Socket(args [0]、80)を介して接続されます。ソケットクラスのコンストラクターは、定義するときにスローを使用するため、Socketクラスコンストラクターを呼び出すときは、Try ... CATCHステートメントを使用してエラーをキャッチするか、スローステートメントを使用してメイン関数のエラーをスローします。
ソケットクラスを使用してサーバーに接続して、ホストにどのポートが開かれているかを決定します。次のコードは、このマシンでどのポートが開かれているかをスキャンするプログラムです。
2。データの送信と受信
ソケットクラスで最も重要な2つの方法は、getInputStreamとgetOutputStreamです。これらの2つの方法は、それぞれデータを読み書きするための入力ストリームおよび出力ストリームオブジェクトを取得するために使用されます。ここの入力ストリームは、サーバープログラムによってクライアントに送信されたデータを読み取り、outputStreamはクライアントがサーバープログラムに送信したいデータです。
実際のネットワーククライアントプログラムを作成するとき、getInputStreamまたはgetOutputStreamを使用するか、最初に使用する人と後で使用する人は、特定のアプリケーションによって決定されます。たとえば、Post and Telecommunications Press Webサイト(www.ptpress.com.cn)の80ポート(通常はHTTPプロトコルで使用されるデフォルトのポート)に接続し、文字列の送信、最後にwww.ptpress.com.cnから返品された情報を読みます。
パッケージMySocket; Import Java.net。*; Import java.io.*; public class myConnection2 {public static void main(string [] args)throws Exception {socket socket = new Socket( "www.ptpress.com.cn"、80); //サーバーにデータを送信しますoutputStream ops = socket.getOutputStream(); outputStreamWriter opsw = new outputStreamWriter(OPS); BufferedWriter bw = new BufferedWriter(OPSW); bw.write( "hello world/r/n/r/n"); bw.flush(); //サーバープログラムからデータを受信しますinputstream ips = socket.getinputStream(); inputStreamReader IPSR = new inputStreamReader(IPS); BufferedReader BR = new BufferedReader(IPSR);文字列s = ""; while((s = br.readline())!= null)system.out.println(s); socket.close(); }}上記のコードを書くときは、次の2つのポイントに注意を払う必要があります。
1.データ送信の効率を改善するために、ソケットクラスは書き込み方法が呼び出されるたびにデータを送信しませんが、バッファに転送されるデータを書き込み(デフォルトは8192バイト)、フラッシュメソッドを介してこのバッファーのデータを一緒に送信します。したがって、bw.flush();必要です。
2.文字列の送信時に「/r/n/r/n」がHello Worldの後に「/r/n/r/n」が追加される理由は、HTTPプロトコルヘッダーが「/r/n/r/n」をエンドフラグとして使用するためです(HTTPプロトコルの詳細な内容については後で説明します)。したがって、文字列を送信した後に「/r/n/r/n」を追加することにより、サーバープログラムはHTTPヘッダーが終了し、処理できると考えることができます。 「/r/n/r/n」が追加されていない場合、サーバープログラムはHTTPヘッダーの終了、つまり「/r/n/r/n」を待ちます。その場合、サーバープログラムはクライアントに応答情報を送信せず、Br.readline()は、接続のタイミングがタイムアウトするまで応答情報を読み取ることができないためブロックされます。
3。ネットワーク接続をオフにします
これまでのところ、ソケットクラスの基本的な使用方法を予備的に理解していますが、ソケットクラスがデータを処理した後、最も合理的なエンディング方法は、ソケットクラスのクローズメソッドを使用してネットワーク接続を閉じることです。緊密な方法が使用されていますが、ネットワーク接続を閉じる方法は単なる緊密な方法ではありません。どのような状況でJavaがネットワーク接続をシャットダウンできるかを見てみましょう。
ネットワーク接続を閉じることができる4つの状況があります。
これらの4つの方法はすべて同じ目標を達成できますが、最初または2番目の方法を使用してネットワーク接続を閉じることをお勧めします。これは、3番目と4番目の方法が通常、ネットワーク接続をすぐに閉じないためです。その場合、一部のアプリケーションでは、多数の役に立たないネットワーク接続が残り、大量のシステムリソースが占有されます。
ソケットオブジェクトが閉じた後、ISClosedメソッドを使用して、ソケットオブジェクトが閉じた状態にあるかどうかを判断できます。ただし、ISClosedメソッドを使用して返されるのは、ソケットオブジェクトの現在の状態です。つまり、ソケットオブジェクトが正常に接続されているかどうかにかかわらず、ISClosdeは閉じた状態にある限りTRUEを返します。接続されていないソケットオブジェクトを作成するだけの場合、iscloseもtrueを返します。次のコードに示されているように、falseは出力されます。
socket socket = new socket(); system.out.println(socket.isclosed());
ISCloseメソッドに加えて、ソケットクラスには、ソケットオブジェクトが正常に接続されているかどうかを判断するためのISConnectedメソッドもあります。この名前を見ると、読者はそれを誤解する可能性があります。実際、ISConnectedメソッドは、ソケットオブジェクトの現在の接続ステータスではなく、ソケットオブジェクトが正常に接続されているかどうかを決定します。それが正常に接続されている場合、たとえiscloseが真に返されたとしても、IsConnectedは依然としてtrueを返します。したがって、現在のソケットオブジェクトが接続された状態にあるかどうかを判断するには、ISCloseおよびIsConnectedメソッドを同時に使用する必要があります。つまり、ソケットオブジェクトは、ISCloseがfalseを返し、IsConnectedがtrueを返す場合にのみ接続された状態です。次のコードは、上記のソケットオブジェクトのさまざまな状態の生成プロセスを示しています。
パッケージmysocket; Import Java.net。*; public class myCloseConnection {public static void printState(socket socket、string name){system.out.println(name + ".isclosed():" + socket.isclosed()); System.out.println(name + ".isconnected():" + socket.isconnected()); if(socket.isclosed()== false && socket.isconnected()== true)system.out.println(name + "in connected state!"); else system.out.println(name + "in connected state!"); System.out.println(); } public static void main(string [] args)exception {socket socket1 = null、socket2 = null; socket1 = new Socket( "www.ptpress.com.cn"、80); printState(socket1、 "socket1"); socket1.getOutputStream()。close(); printState(socket1、 "socket1"); socket2 = new Socket(); printState(socket2、 "socket2"); socket2.close(); printState(socket2、 "socket2"); }}上記のコードを実行した後、次の出力が表示されます。
socket1.isclosed():false
socket1.isconnected():true
Socket1は接続された状態です!
socket1.isclosed():true
socket1.isconnected():true
Socket1は接続されていない状態です!
socket2.isclosed():false
socket2.isconnected():false
Socket2は接続されていない状態です!
socket2.isclosed():true
socket2.isconnected():false
Socket2は接続されていない状態です!
出力の結果から、Socket1の出力ストリームが閉じた後、Socket1も自動的に閉じられていることがわかります。上記のコードでは、サーバーに接続されていないソケットオブジェクトSocket2の場合、IsClosedメソッドが誤っていることがわかります。 socket2 isclosedメソッドがtrueを返す場合、socket2.closeを使用して、閉じる方法は表示可能に呼び出さなければなりません。
ほとんどの場合、ネットワーク接続を閉じるためにソケットクラスまたは入力および出力ストリームの閉じる方法を使用できますが、出力ストリームまたは入力ストリームのみを閉じたい場合があり、入力と出力のストリームを閉じている間、ネットワーク接続を閉じません。これには、ソケットクラスの他の2つの方法、ShutdownInputとShutDownOutputを使用する必要があります。これらの2つの方法は、対応する入力と出力ストリームのみを閉じますが、同時にネットワーク接続を閉じる機能はありません。 ISClosedおよびIsConnectedメソッドと同様に、ソケットクラスは、ソケットオブジェクトの入力ストリームと出力ストリームが閉じているかどうかを判断する2つの方法も提供します。これらの2つの方法は、isputshutdown()とisoutputshutdown()です。次のコードは、入力ストリームと出力のみを閉じるプロセスを示しています。
パッケージmysocket; Import Java.net。*; public class mycloseconnection1 {public static void printstate(socket socket){system.out.println( "isinputshutdown:" + socket.isputshutdown()); system.out.println( "isoutputshutdown:" + socket.isoutputshutdown()); system.out.println( "isclosed:" + socket.isclosed()); System.out.println(); } public static void main(string [] args)スロー例外{socket socket = new socket( "www.ptpress.com.cn"、80); printState(socket); socket.shutdowninput(); printState(socket); socket.shutdownoutput(); printState(socket); }}上記の世代を実行した後、次の出力を取得します。
isinputshutdown:false
isOutputShutdown:false
isclosed:false
isinputshutdown:true
isOutputShutdown:false
isclosed:false
isinputshutdown:true
isOutputshutdown:true
isclosed:false
出力の結果から、ISClosedメソッドは常にFALSEを返すことがわかります。そのため、ShutdownInputとShutdownOutputがソケットオブジェクトのステータスに影響しないことが確実です。
この記事があなたに役立つことを願っています。これは、Javaがソケットクラスを使用してデータコンテンツを受信および送信することです。みんなが私たちのウェブサイトをフォローし続けることを願っています! Javaを学びたい場合は、このWebサイトをフォローし続けることができます。