DESC
    URI( Address )に含むことができない文字コードを使用できる文字に変換する
    RFC では Percent-Encoding という名称
    文字列データをURLに埋め込むようなときは
    Webサーバとの間で正しく情報をやりとりするために
    別の表記形式に変換する(エンコードする)必要がある
    URI の規則を定める RFC 3986 では URI に
    ASCII の非予約文字以外の文字データを用いる場合には
    「%xx」( xxは16進数 )という形でコードを表記することが定められている
    こんな問題がある
    問題は.
      日本語( 2 byte 文字 ) ServletEngine( Tomcat )で正しく変換されないこと
      Client からの 日本語をうけつける際に, 文字化けをおこすこと
    要は, 
      Gateway が 解釈できるように, 1 byte 文字に変化してしまう 
      データをURLに埋め込んでも問題が生じないように
      英数字以外の文字や/などの記号を安全な形に変換することが目的
      
     ( さらに SPC, 制御文字も可視化する ) 
        その際にどの文字コードを用いるかは実装によって異なる
               
      Rule からはみ出る文字は, URLEncode( 16 進 ASCII 表記 ) される
      SPACE < -> 
            
            Opera( Yahoo::jisyo ) で試してみた. 
            [+] ---> [%2B]        # ASCII ですね. 
            [ ] ---> [+]
            [&] ---> [%26]
            [?] ---> [%3F]        # ASCII ですね. 
    変換方法
          1. Byte 単位でされる.
          1. 第1 Byte -> 16 進. 
          1. 第2 Byte -> ASCII の文字範囲に収まる場合は, そのままの文字. 
          1. 各項目は [&] を接続文字になる
http://house.o-uccino.jp/detail_0006131464_h/
        ただし、URL エンコードの変換方法は JavaScript と CGI では一部異なる
        スペースは JavaScript の場合には %20 に変換されるが、
        CGIでは + に変換される
    URLEncoding が必要な理由
      メール( SMTP )や HTTP などのパケット( Dataの塊 )は
      ヘッダ部に宛先, その他メッセージの制御に関わる情報が追記されてます
      このヘッダは途中のゲートウエーを幾つか中継され、端から端のノードに伝達されます
      これらのノードに理解できるコードと文字で表現されなければならない
      ヘッダ部に日本語のような 2 バイト文字が入ると、
      ノードはこれを 1 バイトずつ解釈して誤解してしまう
      
      これを避けるため URL エンコードができた
      名前と値にある「安全でない」文字は"%xx"に変換する
      "xx"はその文字のASCII値を16進表示したもの
      しかし送られる情報をすべて「見える」文字列に変換するのは都合が良いことが多く
      ボディ部分にも使われる
    ボディ部分の変換にはもうひとつ
    MIME(Multi-Purpose Internet Mail Extensions)エンコーディングがある
    これは2バイトのバイナリ・データを3バイトの
    7ビットASCII(American Standard Code for Information Interchange)
    文字に変換するもので
    マルチメディア情報の転送に使われる
  
    RFC 2396 2.4
   Browser で実行される URLEncode は htm file の文字コードでされるみたいです
    Encode する文字
      変換するのは 
        [ = & % + ]
        プリントできない文字
        
        [&] -> [%26]
        [%] -> [%25]
        [+] -> [%2B]
        [=] -> [%3D]
        [< ] -> [%3C]
        [>] -> [%3E]
      特別なルールとして
        ASCII スペース[ ] -> [+] 
  Encode しない文字
  IE をつかって google で検索をすると URLEncode の結果がみれます
".NET TIPS"
を検索したときには
検索結果の画面でのURL(IEの[アドレス]部分)が次のようになっているはずだ
 このURLでは
  検索文字列  ".NET TIPS" が
  「%22.NET+TIPS%22」にエンコードされている(「"」が「%22」に
  半角スペースが「+」に変換される
  POINT
    IE が自動的にエンコードをしてるが
    プログラムで同様のリクエストを送信するときは
    文字列データを自前でエンコードすること
 
    URL に Encode が必要な文字を含めるには URLEncode 変換後の文字をいれる
    "B&B" を URL に含めたい
    "&" は変換する文字 -> "%26"
    "B%26B"
 
    変換するには, 単に 1byte ずつ %[16進数]といいかえるだけ
    byte をなめるので 文字コードによって表記はかわる
    POINt
        % とついていないのは そのまま ということ
    // ASCII Code は Encode しなくてもいいです
    Lucky池田 < -> Lucky%92r%93c
 
    
    // SJIS [あ] を UrlEncode 
    あああ < -> %82%A0%82%A0%82%A0
    // [ニュース速報] を UrlEncode
    EUC-JP
    %A5%CB%A5%E5%A1%BC%A5%B9%C2%AE%CA%F3
    SJIS
    %83j%83%85%81%5B%83X%91%AC%95%F1
    JIS
    %1B%24B%25K%25e%21%3C%259B.Js%1B%28B
    UTF-8
    %E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1  
 
    逆に 何の Encode の URLEncode かを指定しないと元に戻せない
      # [ あああ ] を 辞書ページで検索してみた. ( これこそまさに DB の機能が使えそう. )
      # p = =%E3%81%82%E3%81%82%E3%81%82 
      # あ = %E3%81%82 となる. 
      # あ = E38182 ( これ何の文字コード ? )
  
    elisp/urlencode/src/urlencode.el    
      
      * TextEditor で 文字をかいて , 特定の文字 Code で保存して
        dump して % つけたもの
  TIP
    emacs では urlencode-region なんてものを 利用すると便利
    すべての WebAddress を UTF-8 で Encode する
    たいていの WebApplication 用の言語には URLEncode のメソッドがある
  // C# VB.NET  HttpUtilityクラス(System.Web名前空間
  HttpUtility.UrlEncode( "あいうえお" )
  // Java ( JSP )
  
 
    この文字列が POST のボディ部分
    あるいは GET のクエリとしてはめ込まれるのである
    Tomcat は URL をデコードして Java の使用文字コードの Unicode に変換します
      [ URL からのデータ ]
            |            Decode 前の文字Code は ISO8859_1 とみなして StringObject に変換
                        ( Tomcat が URL を Decode して Java の内部 Code の Unicode に変換 ) 
            |
            |
      [ StringObject ] 
            |            
            |        < - ISO8859_1 の byte 列にもどす
            |        name.getBytes( "8859_1" );
                    URLDecode 直後の状態になる
            |
      [ Byte 列 ]
            |            
            |        Byte 列 を SJIS として, 再度 StringObject をつくる
            |        String( byteArray, "Shift_JIS" )
            |
      
     
  まとめ
    Tomcat で日本語を使った JSP を利用するためには, 次の方法をする
  String wordSjis = new String( word.getBytes("8859_1"), "Shift_JIS" );
 
      
      1. getBytes(“8859_1”) で一旦 Unicode の文字列を
         ISO8859_1(Latin-1) に変換したうえでバイト列へ
      URLデコードしたときのバイト列が得られることになる
      そのバイト列をString(bytes,”Shift_JIS”)のコンストラクタで 
      Shift_JIS のバイト列だと指定して 
      String型のオブジェクト(Unicode)をつくる
  "Shift_JIS" の部分は
  "EUC-JP" , "JISAutoDetect" もともと期待していたエンコーディングを指定する
  "JISAutoDetect" は短い文字列の場合に正しく判定しないことがあるので使用しないほうが好ましい
      
      まずしたうえでバイト列にする
      そうするとURL デコードした直後のバイト列がとれます
      そのうえでそのバイト列をString(bytes,”Shift_JIS”)のコンストラクタでShift_JISの
      バイト列だと指定して String 型のオブジェクト(Unicode)を生成する
      名前と値を=と&でつないでひとつの文字列にする
         EX: name1=value1&name2=value2&name3=value3
          htm の form で送っているやつか. 
         
         POINT
          // 実は [?] 以降は HTTP のヘッダを渡していた. 
          http://server/foo.jsp?name=val&name=val&name=val&
■ MIME
  DESC
    MultiPurpose Internet Mail Expression ( 多目的 internet )
    規格のひとつ. ( Internet で Data のやりとりをする時の規格 )
    internet の 文字 Code は 7bit
    だから binary を扱うときは uuencode で変更して uudecode で戻していた
    
    でも internet が普及したので Programmer でない人がこれをするのは不便
    そこで MIME という規格をつくり, Binary を扱えるようにした
ボディ部分の変換にはもうひとつ
MIME(Multi-Purpose Internet Mail Extensions)
エンコーディングがある( これも Encode  )
1. MultiPurpose Internet Mail Expression ( 多目的 internet )
これは2バイトのバイナリ・データを3バイトの7ビットASCII(American Standard Code for Information Interchange)文字に変換するもので
マルチメディア情報の転送に使われる
( binary から ASCII に置換するのが目的 )
■ 基本的なこと
■ Socket
  DESC
    Socket とは ユーザにとってのデータの出入り口
    ユーザはソケットへデータを読み書きするだけで通信できる。
    ( とりあえず FILE Pointer みたいなものだと思えば OK )
    Socket の裏側の通信 Protocol を意識しなくても通信Programができます
    Socket は 2 つ以上の Soket が関係をもって初めて意味があります
    ( 1 : N であることもある )
 Socketの種類
  DESC
    2 つあります
  Block とは
    パケットがくるまでスレッドがブロックされるモードのこと
    パケット到着まで他の作業はできません
  受信では
  アプリケーションが
  WSARecv 関数か WSARecvFrom ()に受信用のメモリを提供する
  受信前に一つ以上のメモリを用意しておくと
  データが到着したらそのメモリにすぐ配置される
  
  それらの関数を使えば recv 関数か recvfrom 関数の呼びだし時にコピーしなくて済む
  受信用メモリを提供したときに
  すでにデータがあれば
  すぐにそのメモリにコピーされる
  アプリケーションが受信用メモリを用意していないときにデータが到着すると
  ネットワークがお決まりの形式で同期的に処理します
  内部のメモリに保存します
  アプリケーションが 
  setsockopt 関数で受信用の一時メモリの大きさをゼロに設定した場合は例外です
  信頼性が保証されている通信規格では
  アプリケーションがメモリを用意するとその分のデータを受信できる
  信頼性が保証されていない通信規格ではデータを失う
■ Packet
  DESC
    バイト列のことをネットワーク上ではパケットという。
    送信されるデータだけではなく、宛先などの制御情報が含まれる。
    この情報をみてルータなどは制御をする。
    小包での宛先と中身みたいなもの。
■ Protocol
  DESC
    通信プログラムが情報を交換する際の手順や, パケットの内容についての決まりごと
    ネットワークで通信しあうための各ルールを階層構造のモジュール単位でわけている。
    これを プロトコルスイート, プロトコルファミリという ( TCP/IP など )
        [ ソケット ]
          [ HTTP ]
      [ TCP ][ UDP ]
          [ IP ]
 
  
■ ApplicationProtocol
  DESC
    TCP/IP プロトコルがしてくれるのは
    データを送信したり、受信をすることだけ。
    実際のソケットを使ったプログラムでは
    やり取りする情報をどんな形式で、いつどちらから送るかなどの取り決めが必要になる。
    これをアプリケーションプロトコルという。
■ Order
  POINT
    ソケット経由で多バイトのデータを送信する場合は
    アドレスの昇順で送る。
    受信側も同じく昇順で受信する必要がある。
    
    昇順とは data の小さい順番に並べること。階段でいうと上にあがるのと同じ
    送信側と受信側のプロセッサ固有のバイトオーダーが逆になると問題がおきる
    
  POINT
    あるマシンから別マシンへ多バイトのバイナリ値を送る場合は hton*, ntoh * を使うこと。
    もし ネットワークのバイトオーダーとプロセッサ固有のオーダーが同じ場合は
    変換処理はされない。
■ バッファリング
  POINT
    recv(), send() は一対一対応をしていない。
 
  TCPコネクション上を流れるデータは全体でひとつのデータ列とみなせるが
  3箇所のバッファに分かれて存在する。
      send() -> [ SendQ ] ---> [ RecvQ ]  --(recv())--> [ Deliverd ] 
 
    send() は SendQ にすべてのデータが入るまでブロックされる。
    複数の send() が1回の recv() で受け取ることがあるため
    受信するときは メッセージの解析をすることが必須。
    通常は 区切り文字でする。
    
    
■ ソケットの実装
  POINT
    TCP ソケットの理解するには ソケット構造体やプロトコルの仕組みを理解することが大切
    ソケット構造体は次の情報をもつ
    [ローカルIPアドレス]
    [ローカルポート]
    [リモートIPアドレス]   // ローカルソケットの接続先を指定する
    [リモートポート]
    [受信バッファ]
    [送信バッファ]
 
  POINT
    ローカルポートは bind() で明示できる。また初めて使用する際に自動でアサインされる。
    サーバは bind() をコールして明示して、クライアントはお任せするのが普通。
■ ソケットの状態
    [  closed  ] ---> [  ]    
    
  POINT
    send(), recv() に対応関係があるとは限らない
    1回のsend() を複数の recv() で受けとったり
    3回のsend() を1回の  recv() で受けとることもある
    
 
    
  POINT
    TCP ソケットで send(), recv() を呼び出せるのは 状態が Establishing のときだけ
 
    connect()
    
    bind() を指定していないので 他のソケットが利用していないポートが自動でアサインされる
     [ Closed ] -> [ Connecting ] -> [ Establishing ]
     [        ]     [    P    ]
     [        ]     [    P    ]
     [        ]     [    P    ]
     [        ]
  サーバ側
              bind()          listen
     [ Closed ] -> [ Closed   ] -> [ listening ]
     [        ]     [    Q    ]
     [        ]     [         ]
     [        ]     [         ]
     [        ]
     
     connect があった場合に新規ソケットを作成して IP, リモートポートが割り当てられる
     接続可能なソケットリストに入る
     accept() は Establishing なソケットをひとつ返す
      -> 
     [ Establishing ]
     [        ]
     [        ]
  
■ 切断処理の流れ
  POINT
    TCP には正当な切断処理という仕組みがある
    これにより アプリケーションは転送中のデータを損失せずに済む。
  POINT
    切断は双方向に行うことができる。
    close(), shutdown() は データ送信の終了を表明する。
    close() を受けた TCP 側は 送信バッファの情報の残りをすべて送信して
    切断の意思(ハンドシェイク)を送信する。
    これで受け手はこれ以上受信バッファにデータがこないことを確認できる。
    これが recv = 0 ( close() )の意味
    肯定応答があれば送信した側の情報がすべて 受信バッファに格納されたことが確認できる。
    コネクションは Half-Colsed の状態になる
    これを双方に行うことで完全に切断する。
    
  POINT
    ディスクリプタの割り当てが解除されても ソケット自体は TCP に残る。
    これが Time-Wait の状態。
    Time-Wait がある意味は ソケット構造体が存在し続けて
    他のプログラムが同じポートのソケットをバインドすることを防ぐことにある。
    ( EADDINUSE を返す )
    
  POINT
    後から接続を解除する場合
        相手からの解除要求がきて肯定応答をすると Close-Wait 状態に移行する
    [ Establishing ] ---> [ Close-Wait ]
    このとき Application の close() 待ちになる。
    close() を呼ぶと ソケット構造体へのディスクリプタが解除される。
    そして肯定応答が返ると ソケット自体が消滅する。
    ( つまり 互いにすべての情報を相手側に送れたことを確認できるため )