Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Javaで学ぶネットワークプログラミングの基礎

291 views

Published on

HTTP?HTTPS?それURLの先頭につけるオマジナイでしょ?という程度の理解からステップアップしたいあなたの背中をそっと後押します。 Javaを使って簡単なWebサーバーを作り、HTTPプロトコルの基礎を学び、サーバーソケットとソケットを使ったネットワークプログラミングを実践します。 HTTPSがどのような手順で通信をセキュアにするの?プロキシサーバーって誰?ウェルノウンポートってなに?を丁寧に紐解きます。

Published in: Engineering
  • Be the first to comment

Javaで学ぶネットワークプログラミングの基礎

  1. 1. Javaで学ぶ ネットワークプログラミングの基礎 JJUG CCC 2019 Fall #jjug_ccc #ccc_i3 2019-11-23 株式会社オープントーン 渡邉 一夫
  2. 2. #jjug_ccc #ccc_i3 はじめに • TCP/IPのネットワークプログラミングについて • ネットワークプログラミングは言語に依存しません • Javaだけでなく他の言語でも転用可能 • ネットワークを理解する助けになれば幸いです
  3. 3. #jjug_ccc #ccc_i3 自己紹介 • 名前:渡邉 一夫 ( Twitter → @nave_kazu ) • エンジニア歴:20年 • 所属:株式会社オープントーン • 秋葉原 • 勤怠管理システム • ヘルス・メディテック • 観光ビッグデータ • ディープラーニング • AWSのAPNパートナー • エンジニア募集中!
  4. 4. #jjug_ccc #ccc_i3 自己紹介 • 名前:渡邉 一夫 ( Twitter → @nave_kazu ) • Java歴:20年弱 • DB設計してSpring BootでWeb APIを書いたり、 AngularやVue.jsでクライアントを書いたり、 AWSでインフラ構築したり、、フルスタック?エンジニア • JJUG CCCは2014年ごろから参加 • JJUG CCC 2018 Fall、2019 Springで登壇 • SQL実行ツールを作るのがライフワーク
  5. 5. #jjug_ccc #ccc_i3 自己紹介 • 名前:渡邉 一夫 ( Twitter → @nave_kazu ) • その他 • 共著 システム開発のための見積りのすべてがわかる本 • AWS 認定ソリューションアーキテクト–アソシエイト取得 • Study up!( https://studyup.info/ )の運営
  6. 6. #jjug_ccc #ccc_i3 自己紹介 • HEAVY ROTATION → BAND-MAID
  7. 7. #jjug_ccc #ccc_i3 アジェンダ • インターネットの基礎 • インターネット層について • トランスポート層について • アプリケーション層について • Javaでネットワークプログラミング
  8. 8. #jjug_ccc #ccc_i3 インターネットの基礎 • インターネットとは? • インターネットとはインターネット プロトコル スイート を使用し、複数のコンピュータネットワークを相互接続し た、グローバルなネットワークのことである。 Wikipediaより
  9. 9. #jjug_ccc #ccc_i3 インターネットの基礎 • インターネット プロトコル スイート • ホスト間で通信をするための取り決め(プロトコル)を 集めた「規格集」 • 4階層に分かれていて、それぞれ役割を担っている • 下位層になるほど物理的な規格に基づく
  10. 10. #jjug_ccc #ccc_i3 インターネットの基礎 • インターネット プロトコル スイート • 4階層に分かれていて、それぞれ役割を担っている アプリケーション層 システムやサービスに必要な機能を実装 トランスポート層 誤り検出、自動再送要求、輻輳回避など インターネット層 通信エンドポイント リンク層 物理的に繋がった機器間でデータの受渡を行う
  11. 11. #jjug_ccc #ccc_i3 インターネットの基礎 • インターネット プロトコル スイート • 隣り合った階層でやり取りを行う アプリケーション層 トランスポート層 インターネット層 リンク層 アプリケーション層 トランスポート層 インターネット層 リンク層 端末A 端末B
  12. 12. #jjug_ccc #ccc_i3 インターネットの基礎 • パケット • 送信内容をパケットに入れてやり取りする • パケット = 小包 • ヘッダー部とデータ部(ペイロードとも言う)から構成 • ヘッダー部 = 荷札 • データ部 = 荷物 • ヘッダー部には各階層で通信に必要な情報を詰める
  13. 13. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 データ トランスポート層 インターネット層 リンク層 送信したいデータ (Google検索のワード「BAND-MAID」)
  14. 14. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 インターネット層 リンク層 アプリケーション層 固有のヘッダー情報 (検索ワード送信先URL) 送信したいデータ (Google検索のワード「BAND-MAID」)
  15. 15. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 インターネット層 リンク層 アプリケーション層の パケット
  16. 16. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 リンク層 上位層のパケットをデータに
  17. 17. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 リンク層 上位層のパケットをデータに トランスポート層 固有のヘッダー情報 (TCP & ポート番号)
  18. 18. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 ヘッダー データ リンク層 上位層のパケットをデータに
  19. 19. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 ヘッダー データ リンク層 上位層のパケットをデータに インターネット層 固有のヘッダー情報 (IPアドレス)
  20. 20. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 ヘッダー データ リンク層 ヘッダー データ 上位層のパケットをデータに リンク層 固有のヘッダー情報 (MACアドレス)
  21. 21. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 ヘッダー データ リンク層 ヘッダー データ パケットを受け取ったら データ部を上位層に渡す (荷解き)
  22. 22. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 ヘッダー データ リンク層
  23. 23. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 ヘッダー データ インターネット層 リンク層
  24. 24. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 ヘッダー データ トランスポート層 インターネット層 リンク層
  25. 25. #jjug_ccc #ccc_i3 インターネットの基礎 • パケットのフロー (Google検索の例) アプリケーション層 データ トランスポート層 インターネット層 リンク層 Google検索のワードを 取り出す
  26. 26. #jjug_ccc #ccc_i3 インターネットの基礎 • リンク層について アプリケーション層 システムやサービスに必要な機能を実装 トランスポート層 誤り検出、自動再送要求、輻輳回避など インターネット層 通信エンドポイント リンク層 物理的に繋がった機器間でデータの受渡を行う
  27. 27. #jjug_ccc #ccc_i3 インターネットの基礎 • リンク層について • イーサネット(有線LAN)やWi-Fi(無線LAN) • 隣接するネットワークノード間での取り決め アプリケーション層 トランスポート層 インターネット層 リンク層 アプリケーション層 トランスポート層 インターネット層 リンク層リンク層 有線LANWi-Fi
  28. 28. #jjug_ccc #ccc_i3 インターネットの基礎 • リンク層について • イーサネット(有線LAN)やWi-Fi(無線LAN) • 隣接するネットワークノード間での取り決め ネットワークプログラミングでは 無視して良い(乱暴)
  29. 29. #jjug_ccc #ccc_i3 インターネットの基礎 • リンク層について • イーサネット(有線LAN)やWi-Fi(無線LAN) • 隣接するネットワークノード間での取り決め ネットワークプログラミングでは 無視して良い(乱暴) NetworkInterfaceクラスで 情報は取れる
  30. 30. #jjug_ccc #ccc_i3 インターネット層について アプリケーション層 システムやサービスに必要な機能を実装 トランスポート層 誤り検出、自動再送要求、輻輳回避など インターネット層 通信エンドポイント リンク層 物理的に繋がった機器間でデータの受渡を行う
  31. 31. #jjug_ccc #ccc_i3 インターネット層について • IPアドレス • インターネット層における端末識別番号 • 通信エンドポイント(PC、スマホ、サーバー)に割り当て • IPv4とIPv6がある • IPv4は近い将来枯渇する • IPv6がなかなか普及しない
  32. 32. #jjug_ccc #ccc_i3 インターネット層について • IPアドレス IP アドレス値 個数 IPv4 32ビット 43億個 IPv6 128ビット 340澗(かん)個 (340兆の1兆倍の1兆倍)
  33. 33. #jjug_ccc #ccc_i3 インターネット層について • IPアドレスの表現方法 IP 表現方法 例 IPv4 8ビットずつ10進法で「.」区切り 192.168.100.9 IPv6 16ビットずつ16進法で「:」区切り fe80::6d06:f17c:6f89:bc36
  34. 34. #jjug_ccc #ccc_i3 インターネット層について • IPアドレス IP 表現方法 例 IPv4 8ビットずつ10進法で「.」区切り 192.168.100.9 IPv6 16ビットずつ16進法で「:」区切り fe80::6d06:f17c:6f89:bc36 今回はIPv4についてお話を・・・
  35. 35. #jjug_ccc #ccc_i3 インターネット層について • IPv4パケットヘッダー 0 8 16 24 バージョン ヘッダー長 サービス種別 全長 識別子 フラグ 断片位置 生存時間 プロトコル チェックサム 送信元IPアドレス 宛先IPアドレス オプション 0 32 64 96 128 160 192 どのホストから、どのホストへの 通信なのか?
  36. 36. #jjug_ccc #ccc_i3 インターネット層について • ネットワークアドレスとホストアドレス IPアドレス 192.168.100.9 サブネットアドレス 255.255.255.0
  37. 37. #jjug_ccc #ccc_i3 インターネット層について • ネットワークアドレスとホストアドレス IPアドレス 192.168.100.9 サブネットアドレス 255.255.255.0 ネットワークアドレス 192.168.100.0 サブネットアドレスで マスクした結果 2 ホストアドレス 0.0.0.9 サブネットアドレスの 残りの部分
  38. 38. #jjug_ccc #ccc_i3 インターネット層について • サブネット • ネットワークを論理的に細分化する単位 IPアドレス A 192.168.100.9 IPアドレス B 192.168.100.10 IPアドレス C 192.168.101.9 IPアドレス D 192.168.101.10 サブネットアドレス 255.255.255.0
  39. 39. #jjug_ccc #ccc_i3 インターネット層について • サブネット • ネットワークを論理的に細分化する単位 IPアドレス A 192.168.100.9 IPアドレス B 192.168.100.10 IPアドレス C 192.168.101.9 IPアドレス D 192.168.101.10 サブネットアドレス 255.255.255.0 ネットワークアドレス 192.168.100.0 ネットワークアドレス 192.168.101.0
  40. 40. #jjug_ccc #ccc_i3 インターネット層について • サブネット • ネットワークを論理的に細分化する単位 IPアドレス A 192.168.100.9 IPアドレス B 192.168.100.10 IPアドレス C 192.168.101.9 IPアドレス D 192.168.101.10 サブネットアドレス 255.255.255.0 ネットワークアドレス 192.168.100.0 ネットワークアドレス 192.168.101.0 直接の通信は出来ない
  41. 41. #jjug_ccc #ccc_i3 インターネット層について • デフォルトデートウェイ • 内部と外部ネットワークを接続する • ルーターがその役割を果たす IPアドレス 192.168.100.9 デフォルトゲートウェイ 192.168.100.1
  42. 42. #jjug_ccc #ccc_i3 インターネット層について • デフォルトデートウェイ • 内部と外部ネットワークを接続する IPアドレス A 192.168.100.9 IPアドレス B 192.168.100.10 IPアドレス C 192.168.101.9 IPアドレス D 192.168.101.10 サブネットアドレス 255.255.255.0 ネットワークアドレス 192.168.100.0 ネットワークアドレス 192.168.101.0 直接の通信は出来ない
  43. 43. #jjug_ccc #ccc_i3 インターネット層について • デフォルトデートウェイ • 内部と外部ネットワークを接続する IPアドレス A 192.168.100.9 IPアドレス B 192.168.100.10 デフォルトゲートウェイ 192.168.100.1 デフォルトゲートウェイ 192.168.101.1 IPアドレス C 192.168.101.9 IPアドレス D 192.168.101.10 ネットワークアドレス 192.168.100.0 ネットワークアドレス 192.168.101.0 デフォルトゲートウェイを 介して通信する
  44. 44. #jjug_ccc #ccc_i3 インターネット層について • インターネットとイントラネット
  45. 45. #jjug_ccc #ccc_i3 インターネット層について • インターネットとイントラネット • インターネット → グローバルIPアドレスでアクセス • イントラネット → プライベートIPアドレスでアクセス
  46. 46. #jjug_ccc #ccc_i3 インターネット層について • グローバルIPアドレスとプライベートIPアドレス • グローバルIPアドレス → ICANNが管理・割り当て • プライベートIPアドレス → 自組織内で管理・割り当て • 勝手に使えない → グローバルIPアドレス • 勝手に使える → プライベートIPアドレス インターネット イントラネット イントラネットルーター 192.168.1.2 192.168.1.2 123.508.0.1 123.508.0.2
  47. 47. #jjug_ccc #ccc_i3 インターネット層について • グローバルIPアドレスとプライベートIPアドレス • グローバルIPアドレス → ICANNが管理・割り当て • プライベートIPアドレス → 自組織内で管理・割り当て • 勝手に使えない → グローバルIPアドレス • 勝手に使える → プライベートIPアドレス インターネット イントラネット イントラネットルーター 192.168.1.2 192.168.1.2 123.508.0.1 123.508.0.2 世界にひとつだけ イントラネット内に ひとつだけ
  48. 48. #jjug_ccc #ccc_i3 インターネット層について • プライベートIPアドレスの範囲 • RFC 1918で規定 • 3つのクラス(IPアドレス範囲)を定義 クラス IPアドレス範囲 CIDR クラスA 10.0.0.0 ~ 10.255.255.255 10.0.0.0/8 クラスB 172.16.0.0 ~ 172.31.255.255 172.16.0.0/12 クラスC 192.168.0.0 ~ 192.168.255.255 192.168.0.0/16
  49. 49. #jjug_ccc #ccc_i3 インターネット層について • CIDR(サイダー) • ネットワークアドレスの定義方法 CIDR 192.168.100.0/24
  50. 50. #jjug_ccc #ccc_i3 インターネット層について • CIDR(サイダー) • ネットワークアドレスの定義方法 CIDR 192.168.100.0/24 32ビットのうち、 先頭から24ビットが ネットワークアドレス 残りの8ビットが 割り当てられるIPアドレス
  51. 51. #jjug_ccc #ccc_i3 インターネット層について • CIDR(サイダー) • ネットワークアドレスの定義方法 AWSでは頻出ワード AWSの仮装ネットワーク(VPC)作成画面 AWSのサブネット作成画面
  52. 52. #jjug_ccc #ccc_i3 インターネット層について • 特別なIPアドレス(割り当てられないIPアドレス) • ローカルホスト • ネットワークアドレス • ブロードキャストアドレス
  53. 53. #jjug_ccc #ccc_i3 インターネット層について • 特別なIPアドレス(割り当てられないIPアドレス) • ローカルホスト • 127.0.0.1 • 自分自身のホストを表す • ループバックアドレス • 「 localhost 」
  54. 54. #jjug_ccc #ccc_i3 インターネット層について • 特別なIPアドレス(割り当てられないIPアドレス) • ネットワークアドレス • ホストアドレス部のビットがすべて 0 のアドレス IPアドレス 192.168.100.9 サブネットアドレス 255.255.255.0 ネットワークアドレス 192.168.100.0
  55. 55. #jjug_ccc #ccc_i3 インターネット層について • 特別なIPアドレス(割り当てられないIPアドレス) • ブロードキャストアドレス • ホストアドレス部のビットがすべて 1 のアドレス • 同一ネットワークアドレスのホストに一斉配信をする IPアドレス 192.168.100.9 サブネットアドレス 255.255.255.0 ブロードキャストアドレス 192.168.100.255
  56. 56. #jjug_ccc #ccc_i3 トランスポート層について アプリケーション層 システムやサービスに必要な機能を実装 トランスポート層 誤り検出、自動再送要求、輻輳回避など インターネット層 通信エンドポイント リンク層 物理的に繋がった機器間でデータの受渡を行う
  57. 57. #jjug_ccc #ccc_i3 トランスポート層について • TCPとUDP
  58. 58. #jjug_ccc #ccc_i3 トランスポート層について • TCPとUDP • TCP • コネクション型通信 • 受信確認や再送要求 • 送信順を保証する • 負荷は高い • UDP • コネクションレス型通信 • 受信確認や再送要求は無い • 送信順は保証しない • 信頼性より速度重視
  59. 59. #jjug_ccc #ccc_i3 トランスポート層について • TCPとUDP • TCP → HTTP、SSH、FTPなど • UDP → DNS、NTP、DHCPなど
  60. 60. #jjug_ccc #ccc_i3 トランスポート層について • ポート番号 • 接続するサービスのエンドポイント • 16ビット → 65,536個
  61. 61. #jjug_ccc #ccc_i3 トランスポート層について • TCPパケットヘッダー 0 8 16 24 送信元ポート番号 宛先ポート番号 シーケンス番号 確認応答番号 ヘッダ長 予約 コントロールフラグ ウィンドウサイズ チェックサム 緊急ポインタ オプション 0 32 64 96 128 160 宛先ポート番号でどのサービスに 接続するのかを指定
  62. 62. #jjug_ccc #ccc_i3 トランスポート層について • UDPパケットヘッダー 0 8 16 24 送信元ポート番号 宛先ポート番号 パケット長 チェックサム 0 32
  63. 63. #jjug_ccc #ccc_i3 トランスポート層について • ポート番号の種類 • ウェルノウンポート番号は (IANA) が管理 • 送信元ポート番号は1,024~65,535を使用(RFC 6056) 種類 範囲 ウェルノウンポート番号 0 ~ 1,023 送信元ポート番号 1,024 ~ 65,535
  64. 64. #jjug_ccc #ccc_i3 トランスポート層について • ウェルノウンポート番号 TCP/UDP ポート番号 アプリケーション層のプロトコル TCP 20 FTP (データ) 21 FTP (制御) 22 SSH 80 HTTP 443 HTTPS UDP 53 DNS 67 DHCP(サーバ) 68 DHCP(クライアント) 123 NTP
  65. 65. #jjug_ccc #ccc_i3 トランスポート層について • ウェルノウンポート番号 • http://www.google.co.jp/ → 宛先ポート80番を使用 • https://www.google.co.jp/ →宛先ポート443番を使用
  66. 66. #jjug_ccc #ccc_i3 トランスポート層について • ウェルノウンポート番号以外 • http://localhost:8080/ → 宛先ポート8080番を使用
  67. 67. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング
  68. 68. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • インターネット層のIPアドレスを指定する(端末エンドポイント) • トランスポート層のポート番号を指定する(サービスエンドポイント) • トランスポート層のTCP/UDPどちらかを使用する
  69. 69. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスを表現するクラス群 InetAddress Inet4Address Inet6Address IP (Internet Protocol)アドレスを 表すクラス IPアドレスバージョン4 (IPv4)の アドレスを表すクラス IPアドレスバージョン6 (IPv6)の アドレスを表すクラス JDK1.4から導入 JDK1.0から導入
  70. 70. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスを取得する InetAddress inetAddress = InetAddress.getByName( “www.google.co.jp” ); www.google.co.jp/172.217.25.99
  71. 71. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスを取得する InetAddress inetAddress = InetAddress.getByName( “www.google.co.jp” ); DNS問い合わせをする
  72. 72. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスを取得する • DNS問い合わせ • コンピューター同士はIPアドレスでしか通信できない • 人間が覚えやすいように名前を付けたのが「ドメイン名」 • ドメイン名からIPアドレスを調べるプロトコルがDNS • アプリケーション層のプロトコル
  73. 73. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスとポート番号を表現するクラス群 SocketAddress InetSocketAddress プロトコルに関連付けられていない ソケットアドレスを表す IP ソケットアドレス (IP アドレス + ポート番号) を実装 JDK1.4から導入
  74. 74. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • IPアドレスとポート番号を表現するクラス群 InetSocketAddress socketAddress = new InetSocketAddress( “www.google.co.jp” , 80 ); www.google.co.jp/172.217.26.99:80
  75. 75. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCPとUDPを表現するクラス群 Socket SocketChannel TCP接続 DatagramSocket DatagramChannel UDP接続
  76. 76. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCPとUDPを表現するクラス群 Socket SocketChannel TCP接続 DatagramSocket DatagramChannel UDP接続 JDK1.0から導入
  77. 77. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCPとUDPを表現するクラス群 Socket SocketChannel TCP接続 DatagramSocket DatagramChannel UDP接続 JDK1.4から導入 ノンブロッキングI/Oを提供
  78. 78. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCP接続する (Socket) InetAddress inetAddress = InetAddress.getByName( “www.google.co.jp” ); Socket socket = new Socket( inetAddress , 80 ); “www.google.co.jp”の ポート 80 番に TCPで接続する
  79. 79. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCP接続する (Socket) Socket socket = new Socket( “www.google.co.jp” , 80 ); “www.google.co.jp”の ポート 80 番に TCPで接続する
  80. 80. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCP接続する (SocketChannel) InetAddress address = InetAddress.getByName( "www.google.co.jp" ); InetSocketAddress socketAddress = new InetSocketAddress( address, 80 ); SocketChannel socket = SocketChannel.open(); socket.connect( socketAddress ); “www.google.co.jp”の ポート 80 番に TCPで接続する
  81. 81. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • UDP接続する (DatagramSocket) InetSocketAddress socketAddress = new InetSocketAddress( "192.168.100.1“ , 53); DatagramSocket datagramSocket = new DatagramSocket(); datagramSocket.connect(socketAddress); “192.168.100.1” (LAN上のDNS)の ポート 53 番に UDPで接続する
  82. 82. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • UDP接続する (DatagramChannel) InetSocketAddress socketAddress = new InetSocketAddress( "192.168.100.1“ , 53); DatagramChannel datagramChannel = DatagramChannel.open(); “192.168.100.1” (LAN上のDNS)の ポート 53 番に UDPで接続する
  83. 83. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • TCPでアプリケーション層を実装する アプリケーション層 システムやサービスに必要な機能を実装 トランスポート層 誤り検出、自動再送要求、輻輳回避など インターネット層 通信エンドポイント リンク層 物理的に繋がった機器間でデータの受渡を行う
  84. 84. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPでGoogleトップページを要求する • TCPで接続する(クライアントになる)方法を学ぶ • データを送信する(リクエストを送る)方法を学ぶ • データを受信する(レスポンスを受け取る)方法を学ぶ
  85. 85. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • 「HTMLなどのコンテンツの送受信に用いられる 通信プロトコルである」 (Wikipedia) • クライアントから送る「リクエスト」と サーバーから返される「レスポンス」から構成される • テキストの送受信 • TCPで、ウェルノウンポートは80番
  86. 86. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • 代表的なHTTPサーバー • Apache HTTP Server • Microsoft IIS • Nginx • Apache Tomcat
  87. 87. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • ヘッダーとボディー ヘッダー ボディー ・ヘッダーは改行(CRLF)で区切る ・ヘッダーとボディーの境界は空行
  88. 88. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • リクエストのサンプル GET /⏎ ⏎
  89. 89. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • リクエストのサンプル GET /⏎ ⏎ HTTPメソッド 要求するリソース(URL)
  90. 90. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • HTTPメソッド GET リソース要求 POST データ送信 PUT データ送信 HEAD HTTPヘッダーのみ要求 DELETE リソース削除 OPTIONS サーバー調査
  91. 91. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • リクエストのサンプル GET /⏎ ⏎ TCPで80番ポートに接続後、テキストを送信 HTTPメソッドは「GET」 取得要求のリソースは「/」(ルート) 空行を入れてリクエスト完了
  92. 92. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • レスポンスのサンプル GET /
  93. 93. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • レスポンスのサンプル HTTP/1.0 200 OK Content-Type: text/html; charset=ISO-8859-1 <html> ・・・
  94. 94. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • レスポンスのサンプル HTTP/1.0 200 OK Content-Type: text/html; charset=ISO-8859-1 <html> ・・・ HTTPバージョン
  95. 95. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • レスポンスのサンプル HTTP/1.0 200 OK Content-Type: text/html; charset=ISO-8859-1 <html> ・・・ HTTPステータスコードとメッセージ
  96. 96. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • HTTPステータスとメッセージ (一部) 分類 ステータス メッセージ 成功 200 OK 201 Created リダイレクション 300 Multiple Choices 301 Moved Permanently クライアントエラー 400 Bad Request 404 Not Found サーバーエラー 500 Internal Server Error 504 Gateway Timeout
  97. 97. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTP (Hypertext Transfer Protocol) • HTTPステータスとメッセージ (おまけ)
  98. 98. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPでGoogleトップページを要求する • TCPで接続する(クライアントになる)方法を学ぶ • データを送信する(リクエストを送る)方法を学ぶ • データを受信する(レスポンスを受け取る)方法を学ぶ
  99. 99. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • TCPで、ウェルノウンポート80番に接続 Socket socket = new Socket( “www.google.co.jp“ , 80);
  100. 100. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPでGoogleトップページを要求する • TCPで接続する(クライアントになる)方法を学ぶ • データを送信する(リクエストを送る)方法を学ぶ • データを受信する(レスポンスを受け取る)方法を学ぶ
  101. 101. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPのGETリクエストを送信する String request = "GET /rnrn“; OutputStream out = socket.getOutputStream( ); out.write( request.getBytes() ); GET /⏎ ⏎
  102. 102. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPでGoogleトップページを要求する • TCPで接続する(クライアントになる)方法を学ぶ • データを送信する(リクエストを送る)方法を学ぶ • データを受信する(レスポンスを受け取る)方法を学ぶ
  103. 103. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPのレスポンスを受信する InputStream in = socket.getInputStream( ); int data; while (( data=in.read()) != -1 ) { System.out.write( data ); }
  104. 104. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPのレスポンスを受信する HTTP/1.0 200 OK Date: Sun, 17 Nov 2019 11:41:20 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Accept-Ranges: none Vary: Accept-Encoding <!doctype html><html itemscope=“” itemtype=“http://schema.org/WebPage” lang=“ja”><head>・・・
  105. 105. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPのレスポンスを受信する HTTP/1.0 200 OK Date: Sun, 17 Nov 2019 11:41:20 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Accept-Ranges: none Vary: Accept-Encoding <!doctype html><html itemscope=“” itemtype=“http://schema.org/WebPage” lang=“ja”><head>・・・ 空行より前が レスポンスヘッダー
  106. 106. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPクライアント(ブラウザ)を実装する • HTTPのレスポンスを受信する HTTP/1.0 200 OK Date: Sun, 17 Nov 2019 11:41:20 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Accept-Ranges: none Vary: Accept-Encoding <!doctype html><html itemscope=“” itemtype=“http://schema.org/WebPage” lang=“ja”><head>・・・ 空行以降が レスポンスボディー
  107. 107. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPクライアント(ブラウザ)からの要求に応える • TCPの接続を受け取る(サーバーになる)方法を学ぶ • データを受信する(リクエストを受け取る)方法を学ぶ • データを送信する(レスポンスを送る)方法を学ぶ
  108. 108. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPクライアント(ブラウザ)からの要求に応える • TCPの接続を受け取る(サーバーになる)方法を学ぶ • データを受信する(リクエストを受け取る)方法を学ぶ • データを送信する(レスポンスを送る)方法を学ぶ
  109. 109. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept();
  110. 110. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る 受け付けるポート番号を指定 (HTTPのウェルノウンポート80番) ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept();
  111. 111. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る acceptメソッドでリッスン状態(待機状態)にする ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept();
  112. 112. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る > netstat -nao アクティブな接続 プロトコル ローカル アドレス 外部アドレス 状態 PID TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 13432 ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept(); acceptメソッドでリッスン状態(待機状態)にする
  113. 113. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept();
  114. 114. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • TCPの接続を受け取る ServerSocket serverSocket = new ServerSocket( 80 ); Socket socket = serverSocket.accept(); Enter!
  115. 115. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPクライアント(ブラウザ)からの要求に応える • TCPの接続を受け取る(サーバーになる)方法を学ぶ • データを受信する(リクエストを受け取る)方法を学ぶ • データを送信する(レスポンスを送る)方法を学ぶ
  116. 116. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPのリクエストを受信する InputStream in = socket.getInputStream( ); int data; while (( data=in.read()) != -1 ) { System.out.write( data ); }
  117. 117. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPクライアント(ブラウザ)からの要求に応える • TCPの接続を受け取る(サーバーになる)方法を学ぶ • データを受信する(リクエストを受け取る)方法を学ぶ • データを送信する(レスポンスを送る)方法を学ぶ
  118. 118. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPのレスポンスを作成する StringBuilder response = new StringBuilder(); response.append( "HTTP/1.0 200 OK” ).append( “rn” ); response.append( "rn“ ); response.append( "<html><body>“ ).append( “rn” ); response.append( "<h1>hello world.</h1>“ ).append( “rn” ); response.append( "</body></html>“ ); HTTP/1.0 200 OK ⏎ ⏎ <html><body> ⏎ <h1>hello world.</h1> ⏎ </body></html>
  119. 119. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPのレスポンスを送信する OutputStream out = socket.getOutputStream( ); out.write( response.toString().getBytes() );
  120. 120. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを実装する • HTTPのレスポンスを送信する
  121. 121. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • Socketでクライアントを実装 • ServerSocketでサーバーを実装
  122. 122. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • 特殊なHTTPサーバー → プロキシサーバー • イントラネットとインターネットの間に置くサーバー • アプリケーション層で動作 (ルーターはインターネット層) • アクセス制限・ログ収集などセキュリティ的な理由で配置 • イントラネットからのリクエストを代理する • コンテンツをキャッシュして高速ブラウジング
  123. 123. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • プロキシサーバー インターネット イントラネット プロキシ サーバー
  124. 124. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • ブラウザのプロキシサーバー設定 • Chromeの場合、設定 → システム
  125. 125. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • ブラウザのプロキシサーバー設定 • OSのプロキシ設定
  126. 126. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • ブラウザのプロキシサーバー設定 • OSのプロキシ設定
  127. 127. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを起動してブラウザからリクエスト • リクエスト内容 GET http://www.yahoo.co.jp/ HTTP/1.1 Host: www.yahoo.co.jp Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0
  128. 128. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを起動してブラウザからリクエスト • リクエスト内容 GET http://www.yahoo.co.jp/ HTTP/1.1 Host: www.yahoo.co.jp Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 接続先のプロトコルとホストを記載 GET / HTTP/1.1
  129. 129. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPサーバーを起動してブラウザからリクエスト • リクエスト内容 GET http://www.yahoo.co.jp/ HTTP/1.1 Host: www.yahoo.co.jp Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 先頭のメソッド行からプロトコルと ホストを抽出して中継
  130. 130. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPS (HTTP Secure) • Webサーバーとブラウザ間で暗号化通信する仕組み • SSL(Secure Socket Layer)プロトコルを使用 • 今はTLS(Transport Layer Security)プロトコルを使用 • 公開鍵暗号化方式で暗号化 • なりすましやデータ改ざんを検知する • TCPで、ウェルノウンポートは443番
  131. 131. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • 公開鍵暗号化方式 • 公開鍵と秘密鍵の2つの鍵を用いて暗号化する • 公開鍵は公開OK、秘密鍵は公開NG • クライアントはサーバーの公開鍵で暗号化 • サーバーは自身の秘密鍵で復号化 • サーバーの公開鍵を認証局でデジタル署名
  132. 132. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • 公開鍵暗号化方式 サーバー 認証局 (CA) ブラウザ 公開鍵 秘密鍵 第三者(認証局)に 公開鍵の本人性を 確認して署名してもらう 認証局の署名で 公開鍵が正規のもので あることを確認 公開鍵で暗号化して送信 秘密鍵で 復号化
  133. 133. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPSクライアント(ブラウザ)を実装する • HTTPSのGETリクエストを送信する URL url = new URL("https://www.google.co.jp/"); HttpsURLConnection ssl = (HttpsURLConnection) url.openConnection();
  134. 134. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPSクライアント(ブラウザ)を実装する • HTTPSのGETリクエストを送信する URL url = new URL("https://www.google.co.jp/"); HttpsURLConnection ssl = (HttpsURLConnection) url.openConnection(); GET /⏎ ⏎
  135. 135. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPSサーバーを実装する
  136. 136. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPSサーバーを実装する • AWSに任せよう!
  137. 137. #jjug_ccc #ccc_i3 Javaでネットワークプログラミング • HTTPSサーバーを実装する • AWSに任せよう! • ELB(ロードバランサー)を使って、HTTPSをHTTPに転送 • 無料のSSL証明書 • ELBとRoute53に設定して自動更新
  138. 138. #jjug_ccc #ccc_i3 まとめ • インターネット プロトコル スイートの各階層の役割 • インターネット層 → IPアドレス • トランスポート層 → TCP/UDP、ポート番号 • アプリケーション層 → HTTP・HTTPSなどのサービス • 接続にはIPアドレス、ポート番号、TCP/UDPが必要 • 接続後はInput/OutputStreamで通信 • 言語が違っても上記の概念は一緒 • セキュリティ周りは自前で実装より既存のものを
  139. 139. #jjug_ccc #ccc_i3 Thank you for listening!

×