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

RG 第6回
プログラミング実習
20091112
che@ace
今日の予定
• プログラムを書いてみる
– 初心者向けです
• Javaの基礎を学ぶ
– Java未経験の人も安心
• ネットワークプログラミングの基礎を学ぶ
– echoクライアントの実装を通じた学習
• ペアプログラミングによる技術向上
– 新人さんも旧人さんも参加してください
自己紹介
〜 cheって誰? 〜
• 名前:che
– 本名:今枝卓也
• 年齢:四捨五入したら30歳!
• 所属:政策・メディア研究科修士課程
– 徳田・高汐・中澤合同研究会
– ACE最古参
• お仕事:学生(半NEET)
– 来年から某ゲームメーカーに勤務予定
• 趣味:プログラミング
– でも来年からエンジニアじゃなくなります
皆さんに質問
• ネットワークプログラミング未経験の人
– 新人・旧人は問いません
– 言語は問いません
• che集計中・・・
今日の趣旨
• ペアプログラミングをしてもらいます
– 初心者と上級者のペア
– 基本は2人1組
• 人数によっては3人になるかもしれません
• 今回のルール
– 初心者がコードを書く
• 上級者は手を出してはいけない
– 上級者は初心者の横で適宜助言をする
• 口を出すのはOKです
ペアプログラミングについて
• 2人で1台のマシンを使ってプログラムを書く
– 実際にコードを書く人:ドライバー
– 隣にいる人:ナビゲーター
• 利点
– 個人でのプログラミングに比べて2倍以上の効率
– 初心者・上級者どちらにも効果がある
• 欠点
– 共同作業を嫌がる人もいる
ペアプログラミングの利点
Wikipediaより抜粋して引用
•
•
•
•
•
•
•
•
規範意識の増大。ペアプログラミングでは、個人の作業よりもサボりにくく、ちゃんと作
業を進める可能性が高い。
よりよいコード。相乗効果により設計の質が向上することが期待される。
作業効率の向上。1人で作業するときとは流れが変わる。次に何をすべきかを考え込むと
いったことが少なくなる。
多数の開発者による設計。ペアを頻繁に入れ替えれば、複数の人間が1つの機能の開発に
関わることになる。これによりよりよい設計が生み出され、たとえばあるペアが解決でき
ない問題で作業が止まってしまっても、別のペアでは解決できることもある。
勤労意欲の向上。ペアプログラミングの方が1人で作業するよりも楽しいと感じる開発者
もいる。
集団的なコード所有権。プロジェクトの全員がペアプログラミングを行い、頻繁にペアを
組みかえる場合、そのコード全体について全員がそれなりの知識を共有することになる。
教育的側面。初心者であっても固有の知識(プログラミングテクニックなど)を持ってい
るものである。ペアプログラミングでは、余計な手間をかけずにそのような知識をチーム
全体で共有できる。
チームワーク。ペアプログラミングを行うことでチームの各人が互いをよりよく知ること
ができ、結束力を生み出しやすい。
ペア決め
• 上級者の人
– 教室左側へ移動してください
• 初心者の人
– 教室右側へ移動してください
環境構築
• Java SE Development Kit(JDK)をインストールしてくださ
い
– Windowsの人
• SunのJavaページからインストーラをダウンロードして実行
– http://java.sun.com/javase/ja/6/download.html
• 環境変数を設定
– javacというコマンドの入っているディレクトリをPATHに追加
– Macの人
• 最初から入っている可能性が高いです
– 入ってない場合,確認の仕方がわからない人はアシスタントの人に質問してくだ
さい
– Linuxの人
• 各ディストリビューションのパッケージ管理ソフトからインストール
• 上級者の人サポートお願いします
– 上級者の人がJDKインストール済のPCを持ってたら借りるのも
アリです
まずは手始めに
• Hellow worldを書いてみましょう
– コンソールに“Hello, world!”と表示する
Hello worldって?
• 様々なプログラミング言語において初心者が一番最初
に書くプログラム
– “プログラミング言語 C”という本で有名になった
• ブライアン・カーニハン, デニス・リッチー著, 1978
– 著者の名前を取って通称 “K & R”
• C言語の教科書の神様的な存在
– C が標準化される前はこれがリファレンスだった
– “Hello, world!”以外にも多様なバリエーションがある
•
•
•
•
•
感嘆符無し
カンマ無し
全部小文字
etc…
世の中にはELF Golfという崇高なスポーツもある
– Hellow worldをどれだけ小さいサイズでコンパイルできるかを競う
JavaでHello, world!
• テキストエディタで以下のように記述
1: public class HelloWorld {
2: public static void main(String[] argv) {
3:
System.out.println(“Hello, world!”);
4: }
5: }
• “HelloWorld.java”という名前で保存
コンパイル
• ターミナルを起動
– Windowsの場合
• コマンドプロンプトを起動
– Macの場合
• ターミナルを起動
• 先ほどのファイルを保存したディレクトリに移動
• 以下のように入力
% javac HelloWorld.java
% java HelloWorld
Hello, world! ←このように表示されたら成功
ちょっと確認
• コンパイル(javac)はうまくいきましたか?
– “javac: command not found”のように表示されたら
JDKのインストールや環境変数の設定が失敗している
可能性があります
• 上級者の人サポートお願いします
• もしくはアシスタントの人に聞いてください
– それ以外のエラーメッセージが出たらプログラムを
書き間違えています
• とりあえず全員成功するまで待ちます
– 周りで困っている人がいたら助けてあげてください
ちょっと解説
• 1行目:public class HelloWorld {
– 今回はおまじないだと思いましょう
– クラス定義の開始
• 2行目:public static void main(String~
– ここからプログラムが始まる
• 3行目:System.out.println(“~
– “”で囲まれた文字列を表示する
ネットワークプログラミング!
今日の本題
• echo クライアントを書いてみよう
– ネットワーク上のechoサーバに任意の文字列
を送信する
– echoサーバから送り返されてきた文字列を受
け取りコンソールに出力する
echoプログラムって?
• 文字列をそのまま送り返すプログラム
– 今回はネットワークを使ったechoです
1. クライアントはサーバに文字列(例えばhello)
を送る
2. サーバはクライアントから送られてきた文字列
をそのままクライアントに返す
3. クライアントはサーバから送られてきた文字列
を受け取る
– 今回は通信ポートは 10007番を使う
• 普通なら 7番
ちょっと触ってみよう
ローカル編
• ターミナルを起動
• 以下のように入力
% echo hoge
hoge ←echoの次に書いた文字がそのまま表示される
ちょっと触ってみよう
ネットワーク編
• 現在このマシン上でechoサーバが動いていま
す
– アドレス:133.27.
– ポート:10007
• Telnetで接続してみましょう
– 以下のように入力
% telnet 133.27. 10007
– 適当に文字列を入力してみてください
• 今回はこのtelnetのような働きをするプログ
ラムを書いてもらいます
ネットワークの基礎
Webブラウザの例
HTMLファイル
表示
リクエスト
レスポンス
クライアント
133.27.171.196
インターネット
サーバ
www.google.co.jp
(66.249.89.147)
ネットワークの基礎
アプリケーションから見ると
クライアント
サーバ
Webブラウザ
メールクライアン
ト
Webサーバ
リクエスト
メールサーバ
FTPクライアント
FTPサーバ
メディアプレーヤ
CDDBサーバ
…
…
どのアプリ?
ネットワークの基礎
アプリケーションから見ると
クライアント
サーバ
リクエスト
Webブラウザ
Webサーバ
メールクライアン
ト
メールサーバ
FTPクライアント
FTPサーバ
メディアプレーヤ
CDDBサーバ
…
…
ポート
ネットワークの基礎
• クライアントはサーバに接続
– アドレスとポートを指定
•
•
•
•
•
クライアントはサーバにデータ送信
サーバはクライアントからのデータ受信
サーバはクライアントにデータ送信
クライアントはサーバからのデータ受信
…
ネットワークプログラミングの基礎
• 一般的なネットワークプログラムでは通
信にソケットというインターフェースを
使う
– 通信処理を抽象化したもの
– 後で皆さんに実際に使ってもらいます
ネットワークプログラミングの基礎
イメージ
クライアント
クライアント
プログラム
サーバ
接続要求
サーバ
プログラム
ネットワークプログラミングの基礎
イメージ
クライアント
クライアント
プログラム
サーバ
接続確立
サーバ
プログラム
ネットワークプログラミングの基礎
イメージ
クライアント
クライアント
プログラム
サーバ
データ送受信用の
窓口を作る
サーバ
プログラム
ネットワークプログラミングの基礎
イメージ
クライアント
クライアント
プログラム
サーバ
データを送る
サーバ
プログラム
ネットワークプログラミングの基礎
イメージ
クライアント
クライアント
プログラム
サーバ
データを受け取る
サーバ
プログラム
まずは準備
• 以下のファイルをダウンロードして適当
な場所に展開してください
– http://www.ht.sfc.keio.ac.jp/~che/rg/echo.zip
• 中に入っているclientディレクトリの中の
EchoClient.javaをテキストエディタで開い
てください
– EchoClient.javaにはプログラムの骨組みのみ
書かれています
試しに
• コンパイルして実行してみましょう
– 何も起こらないはずですが
– 失敗した場合インストールや環境設定が失敗
している可能性があります
– 全員成功するまでちょっと待ちます
サーバアドレスの設定
• EchoClient.javaの中の1行を書き換える
private static final String DEFAULT_SERVER_ADDRESS =
“localhost”; //これを
↓
private static final String DEFAULT_SERVER_ADDRESS = “133.27.”;
//このように書き換える
Socketを作る
• まずはサーバと接続するSocketを作りま
しょう
• Socketの作り方
– “//ここから書く”の次に以下のように書いてみ
てください
Socket socket =
new Socket(DEFAULT_SERVER_ADDRESS, DEFAULT_PORT);
オブジェクト
• Javaはオブジェクト指向プログラミング
言語
– オブジェクトの集合としてプログラムを記述
する
• オブジェクトって?
– データと処理の集まり
Socket socket;
クラス名
オブジェクト名
データの送受信窓口を作る
• Socketを作っただけではデータの送受信
ができません
– 作ったSocketを通じてデータ送受信を行うた
めの窓口を作りましょう
PrintWriter writerToSocket = new PrintWriter (socket.getOutputStream(),
true); //送信窓口
BufferedReader readerFromSocket = new BufferedReader(new
InputStreamReader(socket.getInputStream())); //受信窓口
データを送信する
• サーバに適当なデータを送ってみましょ
う
– 文字列を送る
writerToSocket.println(“hoge”);
メソッドの呼び出し
• オブジェクトはメソッドと呼ばれる処理
の集合を持っている
• メソッドを呼び出す事でオブジェクトに
様々な仕事をさせる事ができる
writerToSocket.println(“hoge”);
オブジェクト名
メソッド名
引数
データを受け取る
• サーバにデータを送信したら,サーバか
ら折り返しデータが返信されてきます
– 受信用の窓口からデータを受け取りましょう
• 受信用窓口からデータを受け取る
– 文字列データが送られてくるので,文字列を
格納する String 型のオブジェクトを作成する
String responce = readerFromSocket.readLine();
データを表示する
• サーバからデータが送られてきたら,そ
のデータを表示してみよう
• 表示方法は HelloWorldと同じです
System.out.println("response from server: " + response);
データの送受信窓口を閉じる
• ここまでで送受信窓口の仕事はおしまい
です
– 不要になった送受信窓口は自分で閉じなくて
はいけません
• 送受信窓口の閉じ方
writerToSocket.close();
readerFromSocket.close();
Socketを閉じる
• この段階でSocketもお役御免です
– 送受信窓口と同じようにSocketも閉じなくて
はいけません
• Socketの閉じ方
socket.close();
全体のコード
試してみよう
• 以上で最低限のechoクライアントができ
ました
• コンパイルして実行してみよう
% javac EchoClient.java
% java EchoClient
ユーザからの入力を受け付ける
• 決まった文字列しか送れないのはつまら
ないですね
• キーボードから文字列を入力できるよう
にしましょう
– ソケットと同じように受信窓口を作る
キーボードからの入力
• Socketと同じようにキーボード用の受信
窓口を作ってデータを受信する
BufferedReader readerFromConsole = new BufferedReader(
new InputStreamReader(System.in));
String request = readerFromConsole.readLine();
//String型のオブジェクトにキーボードからの入力を格納する
…
readerFromConsole.close(); //終わったら閉じる
繰り返し送受信できるようにする
• 1回通信して終了してしまうと何回も試し
たい時不便ですね
• データの送受信を繰り返すようにしま
しょう
繰り返し処理
• 何度も同じ処理をする
• while文
while(条件式) {
//条件式が真である限りここの処理を繰り返す
}
• 実行の途中で繰り返しを止めたい時はbreak文を書く
– 通常は後述のif文と組み合わせる
while(true) {
break;
//これ以降は実行されない
}
例:繰り返し処理
while(true) {
//無限に繰り返す
}
int i = 0;
while(i < 10) {
//iが10より小さい間ここを繰り返す
i++;
}
終了できるようにする
• 繰り返し送受信できるようにしたらプロ
グラムが終了しなくなってしまいました
ね
• 特定の文字列を入力したらプログラムを
終了するようにしましょう
– “quit”と入力したら終了
条件分岐
• ある条件のときにのみ処理が実行される
ようにする
• if 文
if(条件式) {
//条件式が真なら実行される
} else {
//条件式が偽なら実行される
}
• 例
例:条件分岐
int i = 0;
if(i == 0) {
//実行される
}
if(i == 1) {
//実行されない
}
文字列の比較
• 2つの文字列が同一かどうかを判別する
String string = “hoge”; //hogeという文字列の入ったString
オブジェクトを作成する
if(hoge.equals(“hoge”) {
//実行される
}
if(hoge.equals(“moge”) {
//実行されない
}
全体のコード
試してみよう
• 以上で一通りのechoクライアントプログ
ラムが完成しました
• コンパイルして実行してみましょう
おまけ
• serverディレクトリにサーバのソースコードが
入っています
– 興味のある人は読んでみましょう
• 今回のクライアントを適宜変更する事で様々なプ
ロトコルに対応する事もできます
– HTTPとか
• 今日の授業で質問がある人は気軽に質問に来てく
ださい
– 授業後に捕まえてもらってもいいです
– 普段はτ2階ロフトスペースに住んでます
– メールでも可
• [email protected]
おしまい
ちょっと遊んでみましょう
• 接続先ポートを変更する
• コンパイルして実行
– 適当な文字列を入力