この記事では、JAVA でのネイティブ ソケット通信メカニズムの実装原理を主に紹介します。編集者が非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう。この記事では、JAVA のネイティブ ソケット通信メカニズムの原理を紹介し、それを皆さんと共有します。詳細は次のとおりです:
jdk == 1.8
。知識ポイント
ソケット接続処理
ソケット接続を確立します
import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; // 初始化 socket Socket socket = new Socket(); // 初始化远程连接地址 SocketAddress remote = new InetSocketAddress(host, port); // 建立连接 socket.connect(remote);
ソケットの入出力ストリームを処理します
ソケット接続は実際にはファイル ストリームの処理に似ており、どちらも IO 操作を実行します。
入力ストリームと出力ストリームを取得するコードは次のとおりです:
// 输入流 InputStream in = socket.getInputStream(); // 输出流 OutputStream out = socket.getOutputStream();
を使用します。
// 获取 socket 输入流 private BufferedReader getReader(Socket socket) throws IOException { InputStream in = socket.getInputStream(); return new BufferedReader(new InputStreamReader(in)); } // 获取 socket 输出流 private PrintWriter getWriter(Socket socket) throws IOException { OutputStream out = socket.getOutputStream(); return new PrintWriter(new OutputStreamWriter(out)); }
BufferedReader
与 PrintWriter
データのリクエストとレスポンス
IO パッケージング クラスのサポートにより、文字列形式で直接送信でき、パッケージング クラスはデータを対応するバイト ストリームに変換するのに役立ちます。
HTTP 経由で Baidu サイトにアクセスしているため、追加の出力形式を定義する必要はありません。標準の HTTP 伝送形式を使用して、要求応答を実行できます (一部の特定の RPC フレームワークでは通信形式がカスタマイズされている場合があります)。
リクエストされたデータコンテンツは次のように処理されます:
public class HttpUtil { public static String compositeRequest(String host){ return "GET / HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: curl/7.43.0\r\n" + "Accept: */*\r\n\r\n"; } }
// 发起请求 PrintWriter writer = getWriter(socket); writer.write(HttpUtil.compositeRequest(host)); writer.flush(); 接收响应数据代码如下: // 读取响应 String msg; BufferedReader reader = getReader(socket); while ((msg = reader.readLine()) != null){ System.out.println(msg); }
import java.io.*; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import com.test.network.util.HttpUtil; public class SocketHttpClient { public void start(String host, int port) { // 初始化 socket Socket socket = new Socket(); try { // 设置 socket 连接 SocketAddress remote = new InetSocketAddress(host, port); socket.setSoTimeout(5000); socket.connect(remote); // 发起请求 PrintWriter writer = getWriter(socket); System.out.println(HttpUtil.compositeRequest(host)); writer.write(HttpUtil.compositeRequest(host)); writer.flush(); // 读取响应 String msg; BufferedReader reader = getReader(socket); while ((msg = reader.readLine()) != null){ System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private BufferedReader getReader(Socket socket) throws IOException { InputStream in = socket.getInputStream(); return new BufferedReader(new InputStreamReader(in)); } private PrintWriter getWriter(Socket socket) throws IOException { OutputStream out = socket.getOutputStream(); return new PrintWriter(new OutputStreamWriter(out)); } }
public class Application { public static void main(String[] args) { new SocketHttpClient().start("www.baidu.com", 80); } }
モデル最適化要求
このように、関数の実装には問題ありませんが。しかし、詳しく見てみると、IO の書き込みおよび読み取りプロセス中に IO ブロッキングが発生していることがわかります。つまり:// 会发生 IO 阻塞 writer.write(HttpUtil.compositeRequest(host)); reader.readLine();
public class SingleThreadApplication { public static void main(String[] args) { // HttpConstant.HOSTS 为 站点集合 for (String host: HttpConstant.HOSTS) { new SocketHttpClient().start(host, HttpConstant.PORT); } } }
マルチスレッド
public class MultiThreadApplication { public static void main(String[] args) { for (final String host: HttpConstant.HOSTS) { Thread t = new Thread(new Runnable() { public void run() { new SocketHttpClient().start(host, HttpConstant.PORT); } }); t.start(); } } }
マルチスレッド+スレッドプール処理
public class ThreadPoolApplication { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(8); for (final String host: HttpConstant.HOSTS) { Thread t = new Thread(new Runnable() { public void run() { new SocketHttpClient().start(host, HttpConstant.PORT); } }); executorService.submit(t); new SocketHttpClient().start(host, HttpConstant.PORT); } } }
この方法が最適だと思われます。スレッドが複数のソケット接続を同時に処理でき、各ソケットの入出力データの準備ができていないときにブロックされない場合、より良いものはありますか?この技術を「IO多重化」と呼びます。対応する実装は、JAVA の nio パッケージで提供されます。
以上がJava がネイティブ ソケット通信メカニズムを実装する方法の原理の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。