ネットワークプログラミング

公開日: 2026-07-29 09:23 更新日: 2026-07-29 09:43 1108文字 6 min read ... ページビュー

本稿では、TCPとUDPの2つのネットワークプロトコルの特徴と応用シナリオを紹介し、TCPは接続指向で信頼性の高い伝送であり、データ整合性が要求されるシナリオに適していることを指摘した。UDPは接続がなく、オーバーヘッドが小さく、パケット損失を許容するリアルタイムアプリケーションに適している。次に、InetAddress、Socket、ServerSocket、DatagramSocket、DatagramPacketの使用を含むTCPおよびUDPプログラミングモデル、およびURLプログラミングにおけるバイトストリーム経由でネットワークリソースを効率的にダウンロードする方法について説明します。

ネットワークプログラミング

TCPおよびUDPプロトコル

TCPプロトコル

TCPは接続指向の信頼性の高いトランスポートプロトコルです。通信の前に接続を確立し、確認、再送信、順序付けなどのメカニズムを通じてデータができるだけ完全かつ秩序ある方法で到着するようにする必要があります。

UDPプロトコル

UDPは、データグラム指向のコネクションレスプロトコルです。データの到着や到着順序を保証するものではありませんが、プロトコルのオーバーヘッドが小さく、少量のパケット損失を許容したり、アプリケーション層が信頼性を保証するシナリオに適しています。

TCPまたはUDPの選択は、ネットワークの状態だけではなく、信頼性、遅延、スループット、およびサービス特性に基づいて決定する必要があります。

TCPプログラミング{{TCPぷろぐらみんぐ}}

InetAddressクラス

InetAddressはIPアドレスとそれに対応するホスト情報を示すために用いられる。

  • localhostは、ネイティブを指すホスト名です。
  • 127.0.0.1はIPv4ループバックアドレスです。

クライアントモデルとサーバモデル

TCPは通常、クライアント対サーバモデルを採用します。サーバはServerSocket経由でポートをリッスンし、クライアントはSocketを使用して接続をアクティブに開始します。

image-001
image-001
image-002
image-002

TCPサーバ侧

public class TestServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(7000);
             Socket socket = serverSocket.accept();
             BufferedReader reader = new BufferedReader(
                     new InputStreamReader(socket.getInputStream()));
             PrintWriter writer = new PrintWriter(
                     socket.getOutputStream(), true)) {

            System.out.println("有客户端连接了服务器");
            System.out.println(reader.readLine());

            writer.println("1 + 1 的结果是 2");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

accept()は、クライアントが接続を確立するまで現在のスレッドをブロックします。接続が成功すると、サーバはソケットの入力ストリームを介してデータを受信し、出力ストリームを介してデータを送信する。

TCPクライアント

public class TestClient {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 7000);
             PrintWriter writer = new PrintWriter(
                     socket.getOutputStream(), true);
             BufferedReader reader = new BufferedReader(
                     new InputStreamReader(socket.getInputStream()))) {

            writer.println("我是客户端,1 + 1 = ?");
            System.out.println(reader.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

クライアントとサーバは同時にデータを読み書きできます。双方向チャットを実現する場合、通常は送信と受信を別々に処理し、一方が継続的にブロックして通信を継続できないようにする必要があります。

UDPプログラミング#UDPプログラミング#

DatagramSocket

DatagramSocketはUDPデータグラムを送受信するために使用され、プログラムがデータグラムを送受信する通信エンドポイントとして理解することができます。

DatagramPacket

DatagramPacketはデータグラムを表す.送信時にはカプセル化データ、宛先アドレス、宛先ポートが必要であり、受信時には受信バッファとしてバイト配列を用意する必要がある。

A.エンド·プロシージャ

public class ATestUDP {
    public static void main(String[] args) {
        try (DatagramSocket socket = new DatagramSocket(7004)) {
            byte[] sendData = "hello".getBytes(StandardCharsets.UTF_8);
            DatagramPacket sendPacket = new DatagramPacket(
                    sendData,
                    sendData.length,
                    InetAddress.getByName("localhost"),
                    7003
            );
            socket.send(sendPacket);

            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(
                    receiveData,
                    receiveData.length
            );
            socket.receive(receivePacket);

            String message = new String(
                    receivePacket.getData(),
                    0,
                    receivePacket.getLength(),
                    StandardCharsets.UTF_8
            );
            System.out.println(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Bエンドの手続き

public class BTestUDP {
    public static void main(String[] args) {
        try (DatagramSocket socket = new DatagramSocket(7003)) {
            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(
                    receiveData,
                    receiveData.length
            );
            socket.receive(receivePacket);

            String message = new String(
                    receivePacket.getData(),
                    0,
                    receivePacket.getLength(),
                    StandardCharsets.UTF_8
            );
            System.out.println(message);

            byte[] sendData = "我收到了".getBytes(StandardCharsets.UTF_8);
            DatagramPacket sendPacket = new DatagramPacket(
                    sendData,
                    sendData.length,
                    receivePacket.getAddress(),
                    receivePacket.getPort()
            );
            socket.send(sendPacket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

receive()は、データグラムを受信するまでブロックします。UDPが送受信する各基本単位は、完全なデータグラムです。

URL

URLはUniform Resource Locatorで、ネットワーク上のリソースを検索します。一般的な構造は以下のように表現できる。

协议://主机:端口/路径?参数名=参数值&参数名=参数值

ポート、パス、クエリのパラメータはすべて存在する必要はありません。

URLのプログラミング

Webコンテンツを読む

public class TestURL {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.baidu.com/");
            URLConnection connection = url.openConnection();

            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                            connection.getInputStream(),
                            StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ネットワークファイルのダウンロード

public class URLDownload {
    public static void main(String[] args) {
        String address = "https://copyright.bdstatic.com/vcg/creative/"
                + "65e11b3d96ac8f9b293b2d3486b7c422.jpg@wm_1,"
                + "k_cGljX2JqaHdh dGVyLmpwZw==".replace(" ", "");

        try {
            URL url = new URL(address);
            URLConnection connection = url.openConnection();

            try (BufferedInputStream input = new BufferedInputStream(
                    connection.getInputStream());
                 BufferedOutputStream output = new BufferedOutputStream(
                         new FileOutputStream("d:/lession/java2601/test/a.jpg"))) {

                byte[] buffer = new byte[8192];
                int length;
                while ((length = input.read(buffer)) != -1) {
                    output.write(buffer, 0, length);
                }
                output.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

バイナリファイルをダウンロードするときは、バイトストリームを使用し、バイト単位の処理による不必要なパフォーマンス損失を避けるために、バッファを通して一括して読み書きします。

気に入ったならばコメントを残してくださいね~

... ページビュー
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka