Java には、TCP プロトコル用の 2 つのクラスが用意されており、それぞれクライアント側プログラミングとサーバー側プログラミングで使用されます。アプリケーションが通信を開始する前に、まずクライアント プログラムによって開始される接続を作成する必要があります。また、サーバー側プログラムは常にホストの特定のポート番号をリッスンして、クライアントの接続を待機する必要があります。クライアントでは Socket インスタンスのみを使用する必要がありますが、サーバーでは ServerSocket インスタンスと Socket インスタンスの両方を処理する必要があり、どちらも OutputStream と InpuStream を使用してデータを送受信します。
知識を学ぶための最良の方法は、それを使用することです。これまでのメモを通じて、ホストのアドレス情報を取得する方法はすでにわかっています。ここでは、最初に、トランスポートで TCP プロトコルを使用するソケット プログラミングを学習します。層。
TCPサーバー側
ソケット プログラミングでは、サーバー側はクライアント側よりもはるかに複雑です。サーバーの仕事は、通信端末を確立し、クライアントの接続を受動的に待つことです。次のサーバー側プログラムの例は、コンソール入力から取得したポート番号をリッスンし、クライアントから送信されたメッセージを送り返すために使用されます。
次のようにコードをコピーします。
importjava.net.*;
importjava.text.MessageFormat;
importjava.io.*;
publicclassTCPEchoServer{
privatestaticfinalintBUFSIZE=32;
publicstaticvoidmain(String[]args)throwsIOException{
//TODO自動生成メソッドスタブ
//コンソールから監視対象のポート番号を取得する
if(args.length!=1)
thrownewIllegalArgumentException("パラメータ:<ポート>");
//ポート番号を取得する
intservPort=Integer.parseInt(args[0]);
//ServerSocket オブジェクトのインスタンスをインスタンス化します。
ServerSocketservSocket=newServerSocket(servPort);
System.out.println(MessageFormat.format("リスニングを開始、ポート番号: {0}",args[0]));
//初回受信データの総バイト数
intrecvMsgSize;
//データ受信用バッファ
byte[]receiveBuf=newbyte[BUFSIZE];
//ループを繰り返し、ポート番号をリッスンし、新しい接続リクエストを処理します
while(true){
//ブロックして待機し、リクエストを受信するたびに新しい接続インスタンスを作成します
SocketclntSocket=servSocket.accept();
// 接続されているクライアントの SocketAddress を取得します
SocketAddressclientAddress=clntSocket.getRemoteSocketAddress();
//接続クライアントのアドレス情報を出力します。
System.out.println("Handlingclientat"+clientAddress);
//クライアントからデータを受け取るオブジェクト
入力ストリームin=clntSocket.getInputStream();
//クライアントにデータを送信するオブジェクト
OutputStreamout=clntSocket.getOutputStream();
//クライアントから送信されたデータを読み取った後、クライアントに送信します
while((recvMsgSize=in.read(receiveBuf))!=-1){
out.write(receiveBuf,0,recvMsgSize);
}
// クライアントが接続を閉じるときは、接続も閉じます
System.out.println("クライアントが接続を閉じます");
clntSocket.close();
}
}
}
TCPクライアント
ソケット プログラミングでは、まずクライアントがサーバーに送信し、次にサーバーの応答を受動的に待つ必要があります。次の例では、情報をサーバーに送信し、サーバーからメッセージが送信されるのを待って、それを出力します。
次のようにコードをコピーします。
importjava.io.*;
importjava.net.Socket;
importjava.net.SocketException;
publicclassTCPEchoClient{
publicstaticvoidmain(String[]args)throwsIOException{
//TODO自動生成メソッドスタブ
//コンソールから受け取ったパラメータが正しいかどうかを判断します
if((args.length<2)||(args.length>3))
thrownewIllegalArgumentException(
"パラメータ:<サーバー><ワード>[<ポート>]]");
//サーバーアドレスを取得する
文字列サーバー=引数[0];
//送信する必要のある情報を取得する
byte[]data=args[1].getBytes();
//スレーブパラメータが3つの場合、情報送信用のポート番号を取得します。デフォルトのポート番号は8099です。
intservPort=(args.length==3)?Integer.parseInt(args[2]):8099;
// サーバーのアドレスとポート番号に基づいて Socket インスタンスをインスタンス化します。
Socketsocket=newSocket(サーバー,servPort);
System.out.println("サーバーに接続中...echostring を送信中");
//サーバーから受信したデータオブジェクトである、このソケットの入力ストリームを返します。
入力ストリーム=ソケット.getInputStream();
// このソケットの出力ストリーム、つまりサーバーに送信されるデータ オブジェクトを返します。
OutputStreamout=ソケット.getOutputStream();
// コンソールから受信したデータをサーバーに送信します
out.write(データ);
//データを受信したカウンターはデータの初期オフセットを書き込みます
inttotalBytesRcvd=0;
//受信データの総バイト数を初期化する
intbytesRcvd;
while(totalBytesRcvd<data.length){
//サーバーが接続を閉じると、-1 が返されます。read メソッドは、受信したデータの合計バイト数を返します。
if((bytesRcvd=in.read(data,totalBytesRcvd,data.length
-totalBytesRcvd))==-1)
thrownewSocketException("サーバーへの接続が閉じられました");
totalBytesRcvd+=bytesRcvd;
}
//サーバーから送信されたデータを印刷します
System.out.println("受信:"+newString(data));
//接続を閉じます
ソケット.クローズ();
}
}
まずサーバーを実行し、ポート 8099 でリッスンします。
次に、クライアント プログラムを実行し、サーバーにメッセージを送信します。
サーバー側のコンソールをもう一度見ると、以前のクライアント接続のアドレス情報が表示されます。