WinSock/HTTP通信
HTTP通信

MSDNのコードではsockaddr_in 構造体を使わずにコードを書いている。(MSDNのコードでは addrinfo* 構造体でソケット通信のコードを書いている。)
HTTP通信

だが、Windowsでも、addrinfo* 構造体をつかわずに、sockaddr_in 構造体でも、WinSockのコードを下記のようにして書ける。
HTTP通信

下記コードでは、ローカルホスト(手元のパソコン自身)に接続している。
HTTP通信

実務などでエラー処理などのための場合分けが必要になるだろうだが、しかし上記コードにおいてはエラー処理コードがあるとコードが煩雑になって学習者に分かりづらくなる恐れがあるので、上記コードからはエラー処理を除去してある。
HTTP通信

なお、 inet_pton とは、「pton」の「P」が Presentation の略だと言われており、ここでの「P」は文字列などの意味であり、「n」はNetwaorkの意味であり、
HTTP通信

の意味であり、ptonは、文字列などを、ソケット関連の構造体のもつ情報に変換する命令である。
HTTP通信

逆に、 inet_ntop なら、
HTTP通信

なので、ソケット関連の構造体のもつ情報を、文字列などに置き換える命令である。
HTTP通信

Apathce などのサーバー上のHTMLファイルとどうやって通信するのか、読者は疑問に思ってるだろう。
HTTP通信

さて、実験したいところであるが、しかし、いきなり外部と通信をすると、アクセスが集中したりして迷惑だし、アクセス遮断されたりしかねないので、まず手元のパソコンで試そう。
HTTP通信

Windowsの場合、XAMPPというサーバソフトがあるので、これを手元のパソコンにインストールすれば、ローカルのHTTPサーバを立てられる。
HTTP通信

文字コードの設定など、やや面倒ではあるが、しかしソケット通信のテストなら、英語のままでも構わないので、インストールしてしまおう。
HTTP通信

PHP/確実に動作させるまで にXAMPPの設定方法など書いてあるので、参考に。
HTTP通信

さて、まず、Windows版XAMPPの場合、フォルダ htdocs に、サーバにアップロードしたいファイルを入れる。このhtdocsのような、そこに入れたファイルをサーバにアップロードするフォルダのことを「ドキュメント・ルート」という。
HTTP通信

ともかく、このhtdocsフォルダに、HTMLファイルでもPHPファイルでも何でもいいので、名前をつけてファイルを入れる。
HTTP通信

ただし、「index.html」など一部の名前は、特別な用途が決まっているので、このような名前は避ける必要がある。
HTTP通信

などで、とりあえず「aaaa.html」とか「detarame.html」(デタラメ.html の意味)とか、特別な用途を予約されたファイル名とは重ならないファイル名をつけて、htdocsに入れよう。
HTTP通信

detarame.html に「seikou」(成功)とでも書いておこう。そのメッセージが読めたら、ソケット通信の成功である。
HTTP通信

日本語はパソコンでは非アスキーコードという意味でマルチバイト文字であるが、しかしWindowsのchar型はシングルバイト文字対応の型であり、そしてWinSockのrecv関数はchar型しか認めていないので、どうあがいても、recv関数だけでは、日本語のようなマルチバイト文字を認識できない。なので、WinSockで日本語を処理するのは、文字コード処理に関する、かなり高度なスキルを要求され、面倒である。
HTTP通信

よって、初心者レベルでは、WinSockで日本語を送受信するのは、諦めよう。
HTTP通信

さて、XAMPP および Apacheを起動するのを忘れてはいけない。XAMPPの起動後に表れるXAMPPコントロールパネルから、モジュール『Apache』の欄にある「Start」ボタンを押せばいい。すると、Apatcheが手元のパソコン内で立ち上がる。
HTTP通信

これさえ出来れば、あとは下記のコードをVisual Studio に入力して、実行・ビルドすればいいだけである。
HTTP通信

これを実行すると、下記のような表示結果になる。
HTTP通信

上記コードを実行したら無限にループになる場合、Apacheの立ち上げを忘れている可能性があります。初日は本節を読んでいてXAMPPのApacheを立ち上げるように説明しているので忘れなくても、2日目以降によく立ち上げを忘れるでしょう。
HTTP通信

コード改修で立ち上げ忘れを考慮したコードに改修する事も可能ですが(for文に置き換えるなど)、しかし本節では初学者への分かりやすさの観点から、上記コードはそのまま、ループ箇所をwhile文のままにしておきます。
HTTP通信

いわゆる外部ネットを含む、ウェブサイトとのHTTP通信を行う場合、ポート番号を「80」番に設定する必要があります。この理由は、そういうふうにHTTPの国際規格やTCP/IPの国際規格などがそう決まっているからです。
HTTP通信

一般に、プロトコルの種類や通信の種類などによって、ポート番号が決まっています。
HTTP通信

メール通信になると、なぜか上記とは別のポート番号を使います(読者の混同を防ぐため、メール通信のポート番号については、このページでは紹介しません)。
HTTP通信

読者は「なぜ、プロトコルの種類に応じてポート番号が違うのか?」とか疑問はわくでしょうが、結局は単に昔の人がそう決めてしまっただけです。
HTTP通信

「ポート」と聞くと、あたかも、ハードウェアの何かの端子の番号かのように思えるかもしれませんが、しかしハードウェア端子は一切、ポート番号とは無関係です。
HTTP通信

「ポート番号」とは、その名に反して、実質的な意味はプロトコル番号です。
HTTP通信

コードの送信メッセージの
HTTP通信

で、GETメッセージを送っている。
HTTP通信

なお、1回だけの
HTTP通信

は改行の意味である。ホスト情報など追加の情報を送る場合、1回だけ「\r\n」と入力し、追加情報を1行ずつ入力していく。
HTTP通信

また
HTTP通信

と2個改行が続くことで、送信メッセージ全体がいったん終了する事を意味している(これはUnixソケット通信でも同様)。
HTTP通信

なお、Bad Request の結果の表示は、
HTTP通信

のようになる。
HTTP通信

recv() 関数は、終了時に 0を返し、エラー時に -1 を返すという実装である。
HTTP通信

また、一般にWinSockではエラー時の値は SOCKET_ERROR で表すので、念のため上記コードでは recvの直後のif文に SOCKET_ERROR も加えている。
HTTP通信

実は、recvのブロックのif文は、
HTTP通信

だけでも、とりあえず上記のコードは動くし、正常に終了する。
HTTP通信

一方、
HTTP通信

とか
HTTP通信

だと、無限ループになってしまい、そのままでは終了しなくなるので、閉じるにはコマンドプロンプトのウィンドウ右上の「X」ボタンで閉じるしかない。
HTTP通信

send(destSocket, SendMsg, strlen(SendMsg) , 0); の strlen の長さは、ピッタリと、 strlen(SendMsg)でなければなりません。
HTTP通信

もし、「多いほうが安全かな?」と誤解して strlen(SendMsg)+1 のように大きくしてしまうと、2行目以降の送信メッセージが1文字ずれてしまうためか、もし、
HTTP通信

で送信しようと思っても、送信に失敗します。
HTTP通信

HTTP1.0ではHostメッセージは不要ですが、HTTP1.1ではHostメッセージが必ず必要なので、strlenはピッタリと過不足なくするように注意してください。
HTTP通信

HTTP1.1では、Hostメッセージが必ず必要です。
HTTP通信

Apache のローカルホスト名はそのまま「localhost」ですので、ポート番号の80番とあわせてメッセージを
HTTP通信

のようにHostメッセージを加えて送信することになります。
HTTP通信

sockaddr_in構造体はIPv4用の構造体なので、IPv6では使えません。
HTTP通信

ですが、ほぼ同じ使い方のできるIPv6用の構造体 sockaddr_in6 がありますので、これを使うと IPv6対応のソケットプログラミングが簡単です。なお Linuxでも同様に sockaddr_in6 に置き換える方法で、IPv6対応できます。
HTTP通信

さて、WinSockでも Linuxでも、 AF_INET を AF_INET6 に変える必要があります。
HTTP通信

また、sin_portもsin6_portに、sin_family も sin6_family に変えるなど、 構造体のメンバもIpv6用に更新する必要があります。
HTTP通信

s_addr も s6_addr に更新します。なお Linuxでも同様です。
HTTP通信

手作業でやると大変なので、Visual Studioの一括変換の機能をつかうとラクだし、 更新し忘れによるエラーも防げるでしょう。
HTTP通信

また、Ipv6のローカルホストは::1です。6ケタでなく3ケタなのは不思議に感じるかもしれませんが、国際規格(RFC 4291 など)でそう決まっています。(なお RFCとはw:Request for Commentsのこと)
HTTP通信

なお、「::」というふうにコロンが2個続いた記号の意味は、のこりすべて「0」と言う意味です。
HTTP通信

つまり、「::1」とは、一番右だけが1で、残りは0の、
HTTP通信

という意味です。なお、(2進数ではなく)16進数です。
HTTP通信

なので、たとえば、コードは下記のようになります。
webページのHTTP通信を見るには

FirefoxでもGoogle Chromeでも何でもいいですがwebブラウザで、ファンクションキー F12 を押すと、開発者モードになり、ページ下部にブラウザ内などにある情報が表れます。
webページのHTTP通信を見るには

そこで、いくつも出て来る項目のうち、「ネットワーク」を押すことで、どんなヘッダが送受信されているかを見ることができます。
webページのHTTP通信を見るには

実際、この「WinSock/HTTP通信」で開発者モードでヘッダを見てみると、
webページのHTTP通信を見るには

のような情報を見ることができます。
webページのHTTP通信を見るには

ローカルホストで作成したApacheサーバ上にあるwebページでも同様の方法で、通信ヘッダを見ることができます。
telnet

実は、Visual Studio を使わなくても、telnet (テルネット) という国際規格で決まっている通信形式を使って、WindowsではコマンドプロンプトからHTTP通信が出来ます。
telnet

なお、LInuxなどでも telnet 通信が可能です。
telnet

当然ながらVisual Studio を経由しない通信なので、(visual Studioとは異なり)マイクロソフトへの会員登録も不要です。
telnet

もしWindowsでtelnet通信する場合、まずはコントロールパネルにある「Windowsの機能の有効化または無効化」から(OSバージョンによって多少は手順が異なる)、telnetをインストールします。
telnet

その後、コマンドラインで
telnet

と入力すると、下記のような画面に移り変わります。
telnet

まず、文字が表示されて無い場合があるので、コマンド
telnet

で文字表示をするように設定します。
telnet

すると、成功すれば、
telnet

のような画面になります。
telnet

失敗したり、何かおかしくなったら、コマンド
telnet

または
telnet

でtelnetを終了できます。
telnet

この後、コマンド
telnet

で、ローカルホストにポート80番で接続できます。
telnet

その後、
telnet

のような画面に移り、もう接続しています。
telnet

Windows番では、カーソル位置がおかしな位置に移り、たとえば冒頭の「Microsoft Telnet クライアントへようこそ」の行頭に移ったりしますが、仕様です。
telnet

その後、コマンドで
telnet

とコマンド入力します。
telnet

のような画面になります。
telnet

なお、BackSpace キーや Delete キーは使えません。見た目では、文字は同じでも、telnetはBackSpaceなどのキー情報ごと送信してしまうので、間違えたら、t接続から、やり直す必要があります。
telnet

さらに、コマンド入力は、円ターキーを2回押す必要があります。
telnet

さて、成功すれば、下記のようにメッセージが返ってきます。