この記事では、主に Java Socket について詳しく説明します。Socket は、ServerSocket と Socket の 2 つのカテゴリに分かれています。 JavaのSocketは通常のSocketとNioSocketの2種類に分けて紹介します。
ソケットを 2 つの都市間の交通手段に例えると、2 つの都市間を往復することができ、交通手段にはさまざまな種類があり、それぞれの交通手段にも対応する交通ルールがあります。ソケットも同様で、たくさんの種類があります。ほとんどの場合、安定した通信プロトコルである TCP/IP ストリーム ソケットが使用されます。 (TCP/IP と UDP の比較) Java のネットワーク通信は、Socket を介して実装されます。Socket は、ServerSocket と Socket の 2 つのカテゴリに分けられます。ServerSocket は、accept メソッドを介してリクエストを待機します。 Socket はリクエストをリッスンした後、特にデータ送信を完了するために使用され、クライアントは Socket を直接使用してリクエストを開始し、データを送信します。
ServerSocket の使用は 3 つのステップに分けることができます: 1. ServerSocket を作成します。 ServerSocket の構築方法は全部で 5 つあり、通常は ServerSocket (int port) が使用され、必要なのはポート番号 (port) のみです。2. 作成した ServerSocket の accept メソッドを呼び出してリッスンします。 accept メソッドはブロッキング メソッドです。つまり、accept メソッドを呼び出した後、プログラムは停止して接続要求を待ち、要求が受信されるまでプログラムは続行されません。リクエストを受信すると、accept メソッドは Socket を返します。
3. accept メソッドによって返された Socket を使用してクライアントと通信します。
チェスト
クライアント:
package IO; import java.io.*; import java.net.Socket; import java.util.Date; /** * Created by zhengbin06 on 2017/2/2. */ public class Client { public static void main(String[] args) { String msg = "Client Data"; try { Socket socket = new Socket("127.0.0.1", 9090); // 先写、再读 PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); // 发送数据 printWriter.println(msg); printWriter.flush(); // 获得服务端返回的数据 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = bufferedReader.readLine(); System.out.println("received from server: " + line + "\ttime=" + new Date().getTime()); // 关闭资源 printWriter.close(); bufferedReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
サーバー:
package IO; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; /** * Created by zhengbin06 on 2017/2/2. */ public class Server { private static Socket socket = null; private static ServerSocket serverSocket = null; public static void main(String[] args) throws IOException { BufferedReader bufferedReader = null; PrintWriter printWriter = null; try { // 创建一个ServerSocket监听9090端口 serverSocket = new ServerSocket(9090); while (true) { System.out.println("开始等待请求。。。。"); // 等待请求 // 监听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。 socket = serverSocket.accept(); System.out.println("接收到请求:" + socket.toString() + "\ttime=" + new Date().getTime()); // 接收到请求后使用socket进行通信, 创建BufferedReader用于读取数据 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = bufferedReader.readLine(); System.out.println("received from client: " + line + "\ttime=" + new Date().getTime()); // 创建PrintWriter, 用于发送数据 printWriter = new PrintWriter(socket.getOutputStream()); printWriter.println("received data: " + line + "\ttime=" + new Date().getTime()); printWriter.flush(); } } finally { // 关闭所有资源 bufferedReader.close(); printWriter.close(); socket.close(); serverSocket.close(); } } }
新しいソケットリクエストが来ると、この接続の新しいソケット データ構造。ソケット データ情報には、正式なリクエストの送信元アドレスとポートが含まれます。この新しく作成されたデータ構造は、ServerSocket インスタンス内の未処理の接続データ構造のリストに関連付けられます。この時点では、サーバーの対応する Socket インスタンスは作成されていないため、クライアントとの 3 ウェイ ハンドシェイクが完了するまでサーバーの Socket インスタンスは返されず、Socket インスタンスに対応するデータ構造も作成されないことに注意してください。リスト内の移動はリスト内で実行されます。
データ送信:
接続が正常に確立されると、サーバーとクライアントの両方が Socket インスタンスを持ち、各 Socket インスタンスには InputStream と OutputStream があり、これら 2 つのオブジェクトを通じてデータが交換されます。
ネットワーク I/O はバイト ストリームとして送信されることを知っておく必要があります。Socket オブジェクトを作成するとき、オペレーティング システムは、データの書き込みと読み取りにそれぞれ特定のサイズのバッファー領域を割り当てます。完成しました。書き込み側は、OutputStreamに対応するSendQキューにデータを書き込み、この時点でRecvQが満杯であれば、データは相手側のInputStreamのRecvQキューに転送されます。の OutputStream は、RecvQ キューに SendQ によって送信されたデータを収容するのに十分なスペースが確保されるまでブロックされます。プロセスを以下の図に示します。