okinawa

勉強メモ

新しいプロジェクトに参加したとき用の備忘録

最初にやること

とりあえずシステムを触ってみて、よくわからない所あったらマニュアル見たり、仕様書・設計書をみる。

自分の担当や修正対象のところを重点的に。

気になったところをメモっておく。

コードを理解するのにやったこと

検索や更新のできるだけ簡単な処理をしてそうなところを探す。

デバッグモードでざっと流れを見る。

さらに手動で出てくるクラスをすべて見に行った。たいへん時間かかったけどお陰で全体の構成や処理の流れがわかった。

個人的にはテーブルクラスと1対1になっているモデルクラスを見つけられると理解がしやすい。

1対1のモデルクラスを見つけたら、下記の点を意識しながらみると良き。

  • 画面からモデルクラスにどうやってたどり着くか。
  • DBの検索結果をモデルクラスに格納するのはどこでやってるか。
  • モデルクラスに格納したデータをどうやってViewに渡しているか。

知ってるものに当てはめる。

  • Strutsのバリデーションがわからん時、Springではこうだったよなーとか。
  • ControlllerからDBまでの道筋はStrutsもSpringもほぼ同じはずだよなーとか。

もっと良い方法編み出したら更新したい。

ちなみに今の現場はマニュアルも仕様書も設計書も何もないぞ!

DBも見れないから野生の勘で理解するのだ!!!

コンピュータはなぜ動くのか読んだメモ

参考

回路図書くの大変だったけど、マイコンにちょっと興味が湧いた。

これまた良い本でした。 www.nikkeibp.co.jp

コンピュータの3大原則

1, コンピュータは、入力、演算、出力を行う装置である

2, プログラムは命令とデータの集合体である

3,コンピュータの都合は人間の感覚と異なる場合がある

基本はCPU・メモリ・I/Oの3つ

基本動作は

  1. CPUはクロックジェネレーターが生成するカチカチという信号に合わせて、メモリやI/Oからデータを読み込む。
  2. CPUが読み込んだデータを解釈し、演算する。
  3. 演算結果をCPUからメモリ・/Oに出力する。

■機器の説明

  • CPU:メモリー・I/OのデータをCPUに入力し、内部で演算を行い、結果をメモリー・I/Oに出力する。レジスタという記憶素子も持つ。

  • メモリ:命令+データの記憶装置

  • I/O:周辺機器からのデータ入力(IN)と周辺機器へのデータ出力(OUT)。レジスタを持つ。

レジスタについて 最も高速な記憶素子。

e-words.jp

回路図

ディップスイッチのON / OFFでLEDランプの点灯/消灯をする回路です。

5V=2進数の1。0V=2進数の0。になるようで。

回路図
回路図

うーん、画像が小さくてテキストが読めない・・・。

■機器の説明

  • クロックジェネレーター:クロック信号を生成するための回路。中に水晶が入っているらしい。

  • 3ステートバスバッファ:BUSリクエストがONのときにディップスイッチからメモリに書き込める。OFF時は遮断

  • ディップスイッチ

  • LEDランプ

※BUSリクエストについて

ONにするとCPUが電気的に切り離される。

CPUを介さずにメモリ読み書きをする時用。

BUS(バス)はCPUに繋がっている配線のこと。

■ピンの略号

  • A0~A15:アドレス入出力。
  • D0~D7:データ入出力。0~7の8ビット=1バイトが、一度に入出力できるデータ量。
  • MREQ:メモリ接続要求
  • IQRQ:I/O接続要求
  • B/A:I/OのB or Aレジスタの選択
  • C/D:I/OのControll or Dataレジスタの選択

※B/A・C/Dについて

I/Oのレジスタ指定用。I/Oのレジスタは4つ。

Acontrol / Adata / Bcontrol / Bdata

この4つの切り替えをB/A・C/Dの電圧切替で行う。

■I/Oレジスタのアドレスと役割

  • (0)番ポート=Aポートデータレジスタ。Adata。
  • (1)番ポート=Bポートデータレジスタ。Bdata。
  • (2)番ポート=Aポート制御レジスタ。Acontroll
  • (3)番ポート=Bポート制御レジスタ。Bcontroll

  • Aポートデータレジスタ=ディップスイッチからの入力データ

  • Bポートデータレジスタ=LEDランプへの出力データ

回路図と機械語アセンブリ言語

同じ命令を機械語アセンブリ言語、回路図で表現してみる

命令の内容は

  1. CPUのAレジスタに207という値を書き込む
  2. Aレジスタの値をI/Oの(2)番ポートレジスタに書き込む

機械語

アドレス        機械語
00000000        00111110 // 00111110=LD命令
00000001        11001111 // 11001111=10進数の207
00000010        11010011 // 11010011=OUT命令
00000011        00000010 // 00000010=10進数の2=I/Oの(2)番ポート指定

※命令かデータかの判断はどうやってするの?

命令は予め決められている。

上記の例だと、00111110はLD命令と決められていて、CPUが命令だなと解釈して実行する。

11001111は命令ではないので、207というデータだなと解釈する。

アセンブリ言語

ラベル    オペコード    オペランド
             LD         A, 207 // CPUのAレジスタに207を読み込む
             OUT       (2), A // I/Oの(2)番ポート=AポートControllレジスタにAレジスタの値を書き込む

機械語アセンブリ言語

アドレス        機械語              ラベル    オペコード    オペランド
00000000        00111110  11001111             LD          A, 207
00000010        11010011  00000010             OUT        (2), A

アセンブリ言語の主な命令

  • 演算命令:ADD(加算)・SUB(減算)

  • メモリとCPUの入出力命令:LD(メモリから読み込んでCPUレジスタに書き込む)この命令の時にMREQがONになる。

  • I/OとCPUの入出力命令:IN(I/Oレジスタから読み込んでCPUレジスタに書き込む)・OUT(CPUレジスタからI/Oレジスタに書き込む)これらの命令の時にIORQがONになる。

回路図で表現すると

  1. MREQがON
  2. A0~A7が00000000
  3. D0~D7が00111110
  4. A0~A7が00000001
  5. D0~D7が11001111
  6. IQRQがON
  7. A0~A7が00000010
  8. D0~D7が11010011
  9. A0~A7が00000011
  10. D0~D7が00000010

多分こういう流れになると思う。

XMLとはなんぞや

Extensible Markup Language。

XMLマークアップ言語。

マークアップ言語とはタグによる意味付け言語

<>タグによって意味づけすることをマークアップという。

この意味付けをする言語がマークアップ言語。

HTMLもマークアップ言語。

HTMLとXMLの違いはタグが固定か拡張可能か

HTMLは<body><head>など決められたタグしか使えない「固定的なマークアップ言語」。

XMLは「拡張可能なマークアップ言語」でタグは何を使っても良い!<abc>でも<xxx>でも好きにタグを作れる。

XMLメタ言語

どんなタグを使っても良いということは、どんな使い方をしても良いということ。

つまり新しいマークアップ言語を作れる。

言語を作るための言語を「メタ言語」という。

XMLは情報に意味付けをする

自由にタグを作れるって言っても、一体XMLは何をするものなの?

情報に意味付けをする。

情報に意味付けをするとはいったい・・・。

下記のHTMLとXMLを見比べてほしい。

HTML

<body>
  <p>リン</p>
  <p>10</p>
</body>

XML

<cat>
  <name>リン</name>
  <age>10</age>
</cat>

HTMLでは「リン」と「10」が何を意味するかわからない。

XMLでは猫の名前「リン」で歳が「10」だと意味がわかる。

これが意味づけ。

XML名前空間

タグの名前は自由に作れるので、他の誰かが作ったタグと名前がかぶってしまうかもしれない。

例えば<name>でも人の名前という意味付けをした人、猫の名前という意味付けをした人がいるかもしれない。

そんな時に同じタグを区別するために名前空間を使う。

Namespaces in XML。「xmlns="名前空間"」と書く。

<?xml version="1.0" encoding="UTF-8"?> //←XML宣言
<cat xmlns="https://blog.hatena.ne.jp/dodosu/dodosu.hatenablog.jp"> // ←名前空間
  <name>リン</name>
  <age>10</age>
</cat>

通常は上記のようにURLを名前空間として使用する。絶対にかぶらないから。

区別できるならURLじゃなくても何でも良い。

XMLはコンピュータが見るもの、HTMLは人が見るもの

HTMLはレンダリングしてブラウザに表示して人が見るもの。

XMLはコンピュータが見て意味を解釈するもの。

リンはcatのnameですよ。10はcatのageですよ。ということをコンピュータに伝えている↓

<?xml version="1.0" encoding="UTF-8"?> //←XML宣言
<cat>
  <name>リン</name>
  <age>10</age>
</cat>

XMLからDOM操作でデータを取得

XMLからデータ取得する方法は色々あるようだけど、馴染み深いDOM操作の例をば。

<?xml version="1.0" encoding="UTF-8"?> 
<cat>
  <name>リン</name>
  <age>10</age>
</cat>

上記のXMLから取得する例。

String catName = cat.name;
int catAge = cat.age;

こんな感じでDOM操作で読み込む。

大体どの言語でもXMLをDOMで読み込むコンポーネントがあるらしい。

まとめ

コンピュータの基本まとめ

コンピュータは、入力、演算、出力を行うもの。

プログラムは命令とデータの集まり。

コンピュータの基本構成はCPU、メモリ、I/Oの3つ。

CPUは頭脳、メモリは記憶装置、I/Oは周辺機器との接続。

メモリ or I/O からCPUにデータと命令が入力され、CPUが演算し、結果をメモリ or I/Oに出力する。

XMLまとめ

XMLマークアップ言語を作るメタ言語

<>内のタグは何でも良い!ので自由に新しいマークアップ言語を作れるということ。

目的としては、データに意味付けをすること。

<catName>リン</catName>と書いて「リン」はcatNameですよとコンピュータに伝える。

オブジェクト指向でなぜつくるのかを読んだメモ

参考

最近なぜシリーズにはまっている。

わかりやすくて大変良いです。 www.nikkeibp.co.jp

オブジェクト指向の3大要素

オブジェクト指向はプログラムを簡単にわかりやすく作るためのもの。

カプセル化(クラス)

まとめて隠してたくさん作る。

クラスの目的は整理整頓。

  • まとめる:関連の強いメソッドや変数を1つのクラスにまとめて整理する。
  • 隠す:privateなどで隠して影響範囲を限定する。
  • たくさん作る:インタンスとして大量生産。

1クラスにごちゃまぜにするとわかりにくい。

public class Gotyamaze {
    private String humanName;
    private int accountNumber;
    private int humanAge;
    private String accountType;
}

分けるとわかりやすいよね。

class Human {
    private String humanName;
    private int humanAge;
}

class Account {
    private int accountNumber;
    private String accountType;
}

ポリモーフィズム多態性

メソッドの呼び出し方を共通化する。

異なる処理を同じ方法で呼び出せる。

ポリモーフィズムの目的は共通化

public abstract class Animal {
    public abstract void cry();
}
public class Cat extends Animal{
    @Override
    public void cry() {
        System.out.println("にゃーん");
    }
}
public class Dog extends Animal{
    @Override
    public void cry() {
        System.out.println("ワンワン!");
    }
}
public class Main {

    public static void main(String[] args) {
        // TODO 自動生成されたメソッド・スタブ
        Animal cat = new Cat();
        Animal dog = new Dog();
        cat.cry(); // にゃーん
        dog.cry(); // ワンワン!
    }
}

継承

クラスの継承。

継承の目的は重複を排除すること。

重複部分はスーパークラスに書く。

固有部分はサブクラスに書く。

public class Person {
    private int age;
        private String name;
}
public class Employee extends Person {
    private String CompanyName;
        private String CompnayAddress;
}
public class Student extends Person {
    private String SchoolName;
        private String SchoolAddress;
}

オブジェクト指向以前はどうだったのか

本当の最初は1つのファイルにベタ書きしていた。

そして、サブルーチン(関数)が誕生した。

その後にサブルーチンの独立性を高めるために、ローカル変数と値渡しが生まれた。

あと、昔の言語には条件分岐(if)と繰り返し(for)が書けなかった?

あやふただけど、昔のCOBOLではif文やfor文を素直に書けなかったらしい。

代わりにGOTO文なるものを書いていたらしいが、これがコードの難読化の原因になっていた。

メモリに関する話

なぜ型宣言するのか

静的領域・ヒープ領域・スタック領域

  • 静的領域:プログラム開始時に確保、終了まで固定。1つだけ。static/グローバル変数/コード情報などが入る。
  • ヒープ領域:プログラム実行時に動的に確保するメモリ領域。あらかじめ1つ確保しておく。 必要になったらヒープ領域が割り当てられ、不要になったら削除される。インスタンスが入る。
  • スタック領域:メソッド制御のためのメモリ領域。スレッドごとに1つ。メソッドの引数/ローカル変数/戻り先などの情報が入る。

閃いた!

staticメソッドが非static(インスタンス)を参照できない理由が!

静的領域は最初にメモリ領域が確保される。

対してインスタンスは必要に応じてメモリ領域が割り当てられる。

だから、staticメソッドからインスタンスを参照しようにも、まだインスタンスが存在しないから。

ガベージコレクションの対象となる条件

静的領域とスタック領域から辿れないインスタンスが対象。

インスタンス同士で循環参照していても、静的領域とスタック領域から辿れなければガベージされる。

用語:スレッドとプロセス

どちらもプログラムの実行単位。

プロセスのほうが大きい単位。

スレッドの集まりがプロセス。

スレッド<プロセス

用語:参照とポインタ

Javaで言うところの参照ってポインタと同じ意味なんだって。

知らなかったわあ。

使ってみたいUML

クラス図

クラスの仕様とクラス同士の関連。

ソース理解のために書いてみた。すごくいい。

シーケンス図

インスタンス間の処理の流れを時系列で表現。

アクティビティ図

役割ごとに分けた処理の流れを表現。

頭の整理に良い。

自分ハマったときに処理の流れを細かく分解するのだけど、その時にこれを使うと良さそう。

あと業務分析にも使えそう。

ユースケース

棒人間。

システムの機能と利用者の関係を表現。

これも頭の整理、業務分析に使えそう。

主に役割分担に良さげ。

まとめ

オブジェクト指向はプログラムを簡単に作るためのもの。

3大要素。

カプセル化(クラス)

整理整頓が目的。

関連の強いメソッドや変数をひとまとめにする。

private/protectedなどで影響範囲を限定する。

現実でいうと収納。キッチンの収納にはキッチン用品、玄関の収納には靴、というように関連の強いものを収納する。

メリットは人間にとってわかりやすく、修正しやすいプログラムを書ける。

ポリモーフィズム多態性

メソッドの呼び出し側を共通化する仕組み。

呼び出し方法は同じでも異なる処理が呼び出せる。

現実でいうと「Aさんアレやっといてー」みたいな。

有能なAさんはアレが何かを的確に判断し、その時々で必要なアレを処理する。

メリットは修正が簡易になること。

例えば呼び出される側(メソッド)を増やしても、呼び出し側を修正する必要がない。

・継承

クラスの重複を排除する仕組み。

サブクラスはスーパークラスの定義を含む。

サブクラスにはスーパークラスにはない固有の定義を書ける。

現実でいうと出産?人間の子は手足や頭、遺伝子を親から継承している。

しかし、子供固有の性格や身体的特徴を持つ。

ちょっとこの例えは無理があるかw

メリットは同じコードを何度も書かなくて済むこと。

UML

個人的に使いそうなのは

プログラミングだけでなく、業務分析や頭の整理にも使えそう。

Struts基本のキ

Struts1と2の内容が混在しています。完全に自分用メモです。

Struts2

参考

qiita.com

リクエスト送信→受け取り→レスポンスまでの流れ

jspのformタグからリクエスト送信

f:id:dodosu:20210909133214p:plain

index.jsp

<body>
        <s:form action="message">
            <s:textfield name="age"/>
            <s:submit value="年齢送信"/>
</body>

s:~~~はStrutsのタグライブラリ。

  • s:form action="message":struts.xmlのaction name="message"が呼び出される
  • <s:textfield name="age"/>:アクションクラスのprivate int ageに代入される
struts.xmlで動きを制御
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <!-- アクションのパッケージ定義 -->
    <package name="default" extends="struts-default">
        <action name="message" class="sample.MessageAction" method="ageMessage">
            <result name="fortune">/view/sample/fortune.jsp</result>
            <result name="good">/view/sample/good.jsp</result>
        </action>
    </package>
</struts>
  • action name="message":呼び出し用の名前
  • class="sample.MessageAction":呼び出されるクラス
  • method="ageMessage":呼び出されるメソッド
  • <result name="fortune" /view/sample/fortune.jsp:return "fortune"すると呼び出されるjsp
  • <result name="good" /view/sample/good.jsp:return "good"すると呼び出されるjsp
アクションクラスが呼び出される

MessageAction.java

package sample;

public class MessageAction {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String ageMessage() {
        if (this.age >= 70) {
            return "good";
        }
        return "fortune";
    }
}

struts.xmlに対応したActionクラス、Actionメソッドを作る。

  • private int age:index.jspの<s:textfield name="age"/>の値が入る。勝手にgetter/setterが動くらしい
  • return "good":/view/sample/good.jspが呼び出される
  • return "fortune":/view/sample/fortune.jspが呼び出される
リクエストで受け取った値をjspで表示

f:id:dodosu:20210909133306p:plain

good.jsp

<body>
<s:property value="age"/>才。よく生きましたね。<br>あなたの人生に幸あらんことを。
</body>

fortune.jsp

<body>
<s:property value="age"/>才、あなたの人生に幸あらんことを。
</body>

簡易まとめ

jspでAction名「message」を指定して呼び出す

struts.xml内で「message」を検索

→該当のActionメソッドが呼び出される

→Actionメソッドがreturn forutune or good する

struts.xml内でresultName「'fortune' or 'good'」を検索

→fortune.jsp or good.jspに遷移

jsp内の<s:property value="age"/>は、Actionクラスのage変数から取ってくる

Struts1

参考

非常にわかりやすいのでこっち見たほうが早いかも↓

atmarkit.itmedia.co.jp

Actionクラス

MVCで言うところのController。Actionクラスを継承する。

下記がActionクラスとActionメソッドの基本の書き方。

public class SampleAction extends Action {
  public ActionForward execute (ActionMapping map, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
    SampleAction newForm=(SampleForm)form;
    request.setAttribute("newForm",newForm);
    return map.findForward("success");
  }
}

ActionFormクラス

MVCのModelクラス。ActionFormクラスを継承。

public final class SampleForm extends ActionForm {
  private String name;
  public void setName(String name) {this.name=name;}
  public String getName() {return name;}
}

WebページのForm要素にあるパラメータ値を格納するためのJavaBean。

引用元:2. ActionForm | TECHSCORE(テックスコア)

ActionFormを継承してFormクラスを作るとHTMLのformタグから送られた値をget/setできる。

struts-config.xml

の重要な部分だけ。

下記サイトの画像による説明がめっちゃわかりやすいのでそれを見よう↓

参考:Strutsフレームワークの「枠組み」を学ぶ:Strutsを使うWebアプリケーション構築術(2)(2/2 ページ) - @IT

  • form-beans:Formクラスの場所と名前を定義するだけ。
  • action-mappings:アクションの定義
    • path:jspからの呼び出し名
    • name:アクションクラスが実行された時に実行されるアクションフォームBeanの名前
    • type:アクションクラスの完全修飾名
    • scope:request/sessionのどちらかを設定できる。
  • forward
    • name:Actionクラスでreturn "success"すると呼び出される。
    • path:呼び出されるファイル
<struts-config>
    <form-beans>
   <form-bean name="SampleForm" type="struts.SampleForm" />
  </form-beans>
  
  <action-mappings>
   <action path="/SampleAction" type="struts.BeginProcess"
     name="SampleForm" scope="request">
      <forward name="success" path="/result.jsp" />
    </action>
  </action-mappings>
</struts-config>

ActionMessagesクラス

ページにメッセージを渡すクラス。

エラーメッセージ表示とかに使う。

ActionErrorsというクラスもあり、使い方もほぼ同じ。

メッセージ本文はmessages.propertiesとかから取得。

messages.add(プロパティ, ActionMessage);// メッセージを追加
saveMessages(request, messages); // メッセージを保存

参考:いまさらながらStruts – ActionMessages | 雑廉堂の雑記帳

ActionMappingクラス

struts-config.xmlでアクション名とか決めてる所。

ActionMapping.getAttributeとかでname要素を取得できるんだと思う。

// こんな感じでアクションメソッドの引数にとりあえず入れておく
public ActionForward executeAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)

参考:Strutsリファレンス<action-mapping>

.doの謎

.doが付いてたり、付いてなかったりで混乱した。

  • <html:form>要素内だと.doいらない。自動でつく。
  • その他は.doいる。

.doをつけないとアクションサーブレットが呼ばれない。

呼ばれないとstruts-config.xmlを経由しないのでAction呼べない。

つまり直リンクで画面遷移しかできない。

参考↓ 下のほう、まとめの上あたりに書いてある

atmarkit.itmedia.co.jp

簡易まとめ

jspでActionのpath名「/SampleAction」で呼び出す

struts.xml内で「/SampleAction」を検索

→該当のActionクラスのexecuteメソッドが呼び出される

→同時に「name="SampleForm"」の部分で、SampleFormクラスに値がセットされる。

→Actionメソッドがreturn success する

struts.xml内でforward name「success」を検索

→result.jspに遷移

もっと新しい技術を触りたいなあ(´;ω;`)

ネットワークはなぜつながるのか第2版を読んだメモ

 

参考

とても良い本でした。

www.nikkeibp.co.jp

 

各操作抜粋

各操作の意味がわかったのが、この本を読んで一番良かった点。

(操作)リクエスト・メッセージをF12→ネットワークで見てみる

f:id:dodosu:20210822175600p:plain

大量のリクエス

(操作)自PCのネットワーク詳細の確認

右下のネットのとこクリックネットワークとインターネットの設定

→ネットワークと共有センタ→接続名をクリック→詳細

 

↓こんな感じでIPアドレスやら最寄りのDNSサーバーを設定する。

f:id:dodosu:20210822181433p:plain

(操作)netstat -anoでソケットを見る(TCP担当部分)

f:id:dodosu:20210829094845p:plain

  • ローカルアドレス  自分のIPアドレス : ポート番号
  • 外部アドレス  相手のIPアドレス : ポート番号
  • 状態  通信状態。listening相手からの接続待ち。established通信中。
  • PID  識別番号。タスクマネージャーで調べられる。

(操作)route printでルータの経路表を見る(IP担当部分)

f:id:dodosu:20210909110302p:plain

ゲートウェイの「リンク上」同じネットワーク内にあるので中継いらず、ということ。

 

道順は、インターフェース→ゲートウェイ→宛先、となる。

ASCII.jp:ルーティングの基本動作を見てみよう

 

127.0.0.1localhost。自分自身を表す、ループバックアドレスと言う。

ローカル・ループバック・アドレス(127.0.0.1)とは?:Tech TIPS - @IT

https://wa3.i-3-i.info/word17065.html

(操作)tracert -d で宛先までの道順を見る(IP担当部分)

f:id:dodosu:20210912113116p:plain

IPアドレス8.8.8.8に到達するまでの中継ルーターIPアドレスが表示される。

tracertコマンドでネットワークの経路を調査する【Windows 10トラブル対策】:Tech TIPS - @IT

(操作)arp -aでIPとMACアドレスの対応表を見る(イーサネット担当部分)

f:id:dodosu:20210829112027p:plain

このIPアドレスを持つ機器は、このMACアドレスを持っていますよ、というIPとMACの対応表。 

 

ブラウザ(アプリケーション)のお仕事

URL入力

http:// ウェブサーバー
ftp:// ファイルサーバー URLに入力するとファイルサーバー用ソフトが起動する
mailto:// メールサーバー URLに入力するとメールソフトが起動する

file:// ファイル読み込み

www ワールワイドWEB。インターネットのこと。

例:HTTPプロトコルでWebサーバーにアクセス
http://user:password@www.google.com:80/dir/file1.htm

user ユーザー名(省略可)
password パスワード(省略可)
www ホスト名(ウェブサーバー名)
google.com Webサーバーのドメイン
80 ポート番号(省略可)
dir/file1.htm ファイルのパス名

 

例2:クライアント自身のファイルからデータ読み込み
file://localhost/c:/path/file1.zip

localhot コンピュータ名(省略可
c:/path/file1.zip ファイルパス


ブラウザに「file:///C:/Users/」と打ったらこんな画面が開いた!!! ほえー初めて知ったわ。ブラウザでこんなことできるんやなあ。

f:id:dodosu:20210822180005p:plain

 

例3:メール

mailto :abc@gmail.com

abc@gmail.com メールアドレス

 

URLの解読

https://www.google.co.jp/
 上記のURLを入力するとブラウザは
 httpプロトコル
 www.google.co.jpというドメイン名のWEBサーバー
 に接続するんだなあと解読する。

ファイル名を省略した場合にどこにアクセスするのか?
 デフォルトをindex.htmlとかmain.htmlとかをウェブサーバーに設定しておく。
 そうするとルートディレクトリにあるindex.htmlにアクセスする。
 ↓こんなふうに解読する。
https://www.google.co.jp/root/index.html

 

HTTPリクエストメッセージの作成

リクエスメッセージに書かれていること

何を URI  https://www.google.co.jp/など
どうする HTTPメソッド GET/POST/PUTSなど

リクエスメッセージの中身

リクエストライン:メソッド・ URI・ HTTPバージョン

メッセージヘッダー:リクエストの付加的な情報

メッセージボディ:クライアントからサーバーに送るデータ。GETの場合は空。POSTの場合はFormに入力した値など。

リクエスト・メッセージに書くURLは1つだけ

画像がある場合は、画像の枚数分リクエストを送っているらしい。
画像に限らずjsファイル、CSSファイルなんかの読み込みにもリクエストを送っていると思う。
1つのページを開くのに大量のリクエストが送られていることの謎が解けた。
↓html以外にも大量のリクエストがある。

f:id:dodosu:20210822175600p:plain

大量のリクエス

(操作)リクエスト・メッセージをF12→ネットワークで見てみる

上記画像のようなものが見れる。

 

DNSサーバーに問い合わせ

ブラウザから最寄りのDNSサーバーにwww.google.comというサーバーのIPアドレスを教えて、と問い合わせる。

IPアドレスの基本
  10進数表記 2進数表記    
IPアドレス 10. 1.    2.   3 00001010.00000001.00000010.00000011
サブネットマスク 255.255.255.0 11111111.11111111.11111111.00000000

サブネットマスク2進数表記の「1」の部分がネットワーク部。

「0」の部分がホスト部

 

例: 10.11.12.13/255.255.255.0
全32ビット中の上位24ビットがネットワーク、下位8ビットがホストであることを示す。

10.11.12.13/24でも同じ意味。上位24がネットワーク部ですよということ。

 

f:id:dodosu:20210823084901j:plain

ドメイン名とIPアドレスを使い分ける理由

ドメイン名の方が人間にはわかりやすいが、データ量が多くなってしまうため。
IPアドレス:32ビット
ドメイン名:数十~255バイト

 

(操作)自PCのネットワーク詳細の確認

右下のネットのとこクリックネットワークとインターネットの設定

→ネットワークと共有センタ→接続名をクリック→詳細

 

↓こんな感じでIPアドレスやら最寄りのDNSサーバーを設定する。

f:id:dodosu:20210822181433p:plain

IPアドレスって怖いから隠すけど、DHCPなら毎回変わるし関係なさそう。

最寄りのDNSサーバーがばれる方が危ないのかなあ。

DNSサーバーの基本動作

クライアントからDNSサーバーへの問い合わせ内容

名前 サーバーやメール配送先
クラス 常に「IN」 INはインターネットを表す。最初はインターネット以外も使う想定だった名残。
タイプ A:IPアドレス MX:メール配送先

 

名前 クラス タイプ
www.google.com IN A

↑www.google.comのIPアドレスは?という問い合わせ。

 

DNSサーバーからクライアントへのレスポンス

名前 クラス タイプ レスポンス
www.google.com IN A 192.0.2.226

↑www.google.comのIPアドレスは192.0.2.226だよというレスポンスが返ってくる。

返ってくるのはレスポンス部分だけ。

 

ドメインの階層

例:www.lab.glasscom.com

comドメインが最上位で、comの中のglasscomの中のlabドメインという順に探す。

DNSサーバーも同じ構造になっていて最上位のDNSサーバーにcomが登録されていて、その下位にglasscocom→labが登録されている。

なので、DNSサーバーを上から順にたどっていくと目当てのドメインに辿り着ける。

 

目的のドメインを探す流れ

クライアント→最寄りのDNSサーバー→ルートDNSサーバー→comDNSサーバー→glasscomDNSサーバー→labDNSサーバー→目的のドメインIPアドレス

※最寄りのDNSサーバーはクライアントに設定しておく。

 

URLからIPアドレスを割り出すことを「名前解決」という。

 

プロトコルスタックにメッセージ送信を依頼する

プロトコルスタックとは?

プロトコルスタックとは、コンピュータ上で、通信を実現するための一連の通信プロトコル群を実装しているモジュール(プログラム部品)のことである。
通信プロトコルは階層的な構造を持っている。 その各階層で、それぞれ異なる役割のプロトコルが機能しており、各プロトコルが連携して初めて通信が実現されてる。 例えば、インターネットで用いられているTCP/IPでは、TCPやIPに加えて、HTTP、EthernetIEEE 802.3)などの通信プロトコルが機能しており、それらが連携して初めて通信機能を実現している。 プロトコルスタックは、一揃い(suite)という意味で、プロトコルスイートと呼ばれることもある。 特にTCP/IPの場合は、「インターネットプロトコルスイート」と呼ばれることも多い。 ちなみに、スタック(stack)とは「積み重なり」といった意味である。

 

用語検索 - ZDNet Japan

 

IPアドレスが分かったら、宛先にメッセージを送るようにOS内部にあるプロトコルスタックに依頼します。

具体的にはSocketライブラリのプログラムを決められた順番に呼び出して依頼するらしい。

ちょっとここらへんよくわからなかった。

 

イメージとしては

ソケットというのは通信用の出入り口。

まず、Webサーバー側が通信用のソケットを用意してリクエストが来るのを待ち受ける。

ウェブサーバーはソケット常時用意して、常に待ち受けている。

クライアント側は、通信するときだけソケットを作り、ウェブサーバーまでパイプを繋いで通信をする。

通信が終了したら、パイプを外してソケットを抹消します。

  1. ソケットを作る
  2. サーバー側のソケットにパイプを繋ぐ
  3. データを送受信する
  4. パイプを外してソケットを抹消する

これらの動作はブラウザではなく、OS内部のプロトコルスタックの担当。

ブラウザは依頼するだけ。

 

OSのお仕事 TCP/IP プロトコルスタックとLANアダプタを探検

  1. ソケット作成
  2. サーバー接続
  3. データ送受信
  4. サーバーから切断してソケット抹消
  5. IPとイーサネットの送受信動作

 

ここまでの流れ

 URL入力→URL解読→HTTPリクエスト・メッセージの作成

DNSサーバに問い合わせ→プロトコルスタックにメッセージ送信依頼

 

ソケットの実体(イメージ)

本来は概念的なもので実体はない。

実体↓

(操作)netstat -anoでソケットを見る

f:id:dodosu:20210829094845p:plain

  • ローカルアドレス  自分のIPアドレス : ポート番号
  • 外部アドレス  相手のIPアドレス : ポート番号
  • 状態  通信状態。listening相手からの接続待ち。established通信中。
  • PID  識別番号。タスクマネージャーで調べられる。

 

クライアントからサーバーへの接続動作の実際

クライアントがサーバーのソケットに接続→クライアントがTCPヘッダー作成

→IP担当部にわたす→IP担当部がパケット送信

→サーバー側IP担当部が受け取り、TCP担当に渡す→TCPのヘッダーを解析

→該当するソケットを探し出す→TCP担当が返事返す

TCPヘッダー作成→ここからは同じ→切断動作

 

TCPのお仕事

通信の接続、送受信、切断をIP担当に依頼すること?

主にヘッダー情報の作成してIP担当に渡すまで、というこになるのかしら。

 

IPとイーサネットのパケット送受信動作

ここらへんからハードウェアが出てくる。

xxxxというアドレスはxxxx番目のケーブルだ、みたいな。

 

ルーターとハブ

ルーターはIPのルールでパケット運ぶ

ハブはイーサネットのルールでパケットを運ぶ

 

ルーターが経路表を元に、次の宛先ルーターを特定

ルーターがハブ(イーサネット)に依頼

→宛先ルーターMACアドレスを調べて送る

 

どちらもヘッダー情報を参照しているが

という違いがある。

 

ちなみにIPアドレスはLANアダプタに付与する。

1つのPCにLANアダプタが複数あれば、その数だけIPアドレスがある。

 

プロトコルの流れ:TCP→IP→イーサネット

という順番で依頼していく。

という認識でいいじゃろか。

 

(操作)route printでルータの経路表を見る

f:id:dodosu:20210909110302p:plain

ゲートウェイの「リンク上」同じネットワーク内にあるので中継いらず、ということ。

道順は、インターフェース→ゲートウェイ→宛先、となる。

ARPはIPを元にMACを調べる

ARPはサブネット内のPC全部に「XXXというIPはいますか?いたらMACアドレス教えて」と伝える。

全員に聞く仕組みをブロードキャストという。

 

(操作)arp -aでIPとMACアドレスの対応表を見る

f:id:dodosu:20210829112027p:plain

このIPアドレスを持つ機器は、このMACアドレスを持っていますよ、というIPとMACの対応表。 

 

IPのお仕事

  • IPヘッダーの作成:TCPヘッダーを元に最終目的を知り、それを元に経路表から、次のルータの宛先をヘッダー情報に組み込む
  • MACヘッダーの作成:ARPMACアドレスを割り出し、その情報をMACヘッダーに組み込む。

 此処から先はイーサネットのお仕事。

 

 LAN機器のお仕事 ハブ、スイッチ、ルーター、ケーブル

※ここから先は雑まとめになります。疲れた。

  1. ケーブルとリピーターハブの中を信号が流れる
  2. スイッチングハブのパケット中継動作
  3. ルーターのパケット中継動作
  4. ルーターの付加機能

LAN機器の重要な役割は、信号を劣化させないこと。

 

電話局、プロバイダのお仕事

ADSLとか光ファイバのお話。

サーバー側のLANのお仕事

  • Webサーバー
  • ファイアーウォール
  • 負荷分散
  • キャッシュサーバー

のお話。

 

Webサーバーは社内にあるとは限らない。

データーセンターにあったり、クラウド上にあったりするよ。

ファイアーウォールの仕組み

パケットフィルタリングはパケットのヘッダー情報を元にフィルターする。

IPアドレスMACアドレス・ポート番号など。

例:Webサーバーは送信元ポート番号80以外は遮断する。

Webサーバーのお仕事

サーバーアプリケーションの構造

アパッチやらNginxのこと。

サーバーは複数のクライアントと同時に通信を実行する。

でも、これを1つのプログラムで実現するのは大変。

なので、クライアントが接続してくる都度、新たにプログラムを起動する。

複数のプログラムを同時起動するということ。

 

だから、プログラマーが作るプログラムは1つのクライアント処理だけを意識して作れば良い!

プログラムとクライアントは常に1対1ということになる。

 

ちなみに、接続のたびに新しいプログラムを起動するのはOSのお仕事。

OSがマルチスレッドで頑張ってるんやね。

まとめ

大雑把にMVCでのリクエスト→レスポンスの流れをまとめてみた。

 

  1. ユーザーがリクエスト送信
  2. ブラウザがHTTPリクエストを作成
  3. DNSサーバーに問い合わせて、URLから宛先IPアドレスを解析
  4. ルーターが経路表を元に宛先IPまでの順路を割り出す
  5. arpでネットワーク内の機器に「このIPアドレスをもつ人いますか?」と聞く
  6. 「私が持っています。MACアドレスはXXXXです。」と返答が来る
  7. 5と6を繰り返してWebサーバーにたどり着く
  8. Webサーバーがリクエストごとにプログラムを起動する
  9. apサーバーがリクエストをControllerで受け取る
  10. ControllerがModelに値をセット
  11. ModelがDBに値をセット
  12. DBが結果を返す
  13. Controllerがレスポンスを返す
  14. クライアントがレスポンスを受け取る
  15. ブラウザが画面をレンダリングして表示!

for文でvarを使うと危険

参考

JavaScriptの変数宣言はletにすべきか 『入門JavaScriptプログラミング』から解説:CodeZine(コードジン)

基本

varは関数スコープ。同じ関数ないなあらスコープ外からでも参照可能。

letはブロックスコープ。すこーぷ内からのみ参照可能。

letを使いましょう。

letでfor文

下記の部分をvar i = 0;にしたら上手く行かなかったのでメモ。

for (let i = 0; i < link.length; i++) {}

コメントの中に説明を全部書いてしまった。

JavaScript

  /** for文を var i = 0;にするとだめな理由
   * 前提:varは関数すこーぷ。
   * 前提2:for文は i = 3になった時点でループを抜ける。
   * 前提3:var i = 0;は無名関数のスコープ外で宣言されている。
   * 前提4:iをスコープ外である無名関数の中で使っている link[i].classList.addのところ
   * しかし、varだとループを抜けてスコープ外に出てもi = 3が保持され続ける。
   * だから、イベント発火して、link[i].classList.add('visited');のところで
   * i[3]になってしまい、配列の範囲外エラーが出てしまう。
   * デバッグモードでiの値を見てみるとわかる。
   * */ 
  for (var i = 0; i < link.length; i++) {
    // 各ボタンをイベントリスナーに登録
    link[i].addEventListener('click', function (event) {
      event.preventDefault();

      // visitedクラスを付与
      link[i].classList.add('visited');
    });
  }
});

ちなみにaddEventListenerの中身は、for文で回転中には実行されない。 イベント発火した時に実行される。 なので、for文ではイベント登録がされるだけ。

html

            <p><a class="link" href="#">click1!</a></p>
            <p><a class="link" href="#">click2!</a></p>
            <p><a class="link" href="#">click3!</a></p>

CSS

a {
  color: blue;
}

/* click済みの所を紫にする */
.visited {
  color: purple;
}

どうしてもvarでfor文したいなら

即時関数を使います。

参考

qiita.com

window.addEventListener('load', function () {
  // 複数のlinkクラスを配列で取得する
  const link = document.getElementsByClassName('link');

  for (var i = 0; i < link.length; i++) {
    // 各ボタンをイベントリスナーに登録
    (function () {
      var x = i;
      link[x].addEventListener('click', function (event) {
      
        // visitedクラスを付与
        link[x].classList.add('visited');
        event.preventDefault();
      });
    })();
  }
});

正直意味がわからないけどこれで上手くいく。

なぜ x = i; するのだろうか。

i がスコープ外とはいえ、for文回している最中なら普通に012と増えていくのを参照できそうな気がするんだけど。

そしてもうIE対応はやめて!!!

頼む!!!

JavaScriptのreturn falseでイベント制御

return falseの意味を知らなかったのでメモ。

JavaScriptのイベントってonclickとかaddEventListenerとかでイベント設定して、それを制御するのだけだと思っていた。

けど、htmlのイベントも制御できるようです。

return falseとかで。

  • リンククリック
  • formタグのsubmit

こういうhtmlのイベントをストップできる。

<a id="link" href="google.co.jp">リンク</a>
let link = document.getElementById("link");

link.addEventListener('click', function(e) {

e.preventDefault(); //画面遷移しない
e.stopPropagation(); // 画面遷移しない。
return false; // 画面遷移しない。
});

それぞれの違いなどは下記参考サイトがわかりやすい↓

freelance-jak.com

リンクやsubmitをクリックするとhtmlのイベントより前に、JavaScriptのclickイベントが発生するんですね。