Edited at
移行Day 6

AdventCalendar Day06 [超Ruby入門]


はじめに

本記事は、超Ruby入門6日目の記事です。

コメント頂ける方は、ガイドラインを読んで頂けると幸いです。


目的

C言語を学んだ後に何ができるのかがイメージしづらい。

HTTPサーバをC言語で自作することで、具体的なイメージをつける。


目標


  • socket通信を理解する

  • Wiresharkの基礎的な使い方を習得する


HTTP

そもそもHTTPとはなんだろうか?

HTTPは、通信プロトコルだ。Hypertext Transfer Protocolの名の通り、HTML文書などのリソースを転送するためのアプリケーション層プロトコルだ。


manコマンド


man - format and display the on-line manual pages


manコマンドは、ドキュメントを閲覧することができるUNIXコマンドだ

$ man man (manコマンドのドキュメント)

SOCKET(2)のような表記を見たことがあるだろうか?「2」はセクションの番号を表している。

セクション番号の対応は以下の表の通りだ。


内容

1
汎用コマンド

2
システムコール

3
ライブラリ関数、特に標準Cライブラリ関数

4
特殊なファイル(主に/devにあるデバイス)とドライバ

5
ファイル形式とその使用法

6
ゲームとスクリーンセーバー

7
その他

8
システム管理コマンドとデーモン


例.

$ man 2 socket


Qiitaやブログなどで情報を探すのは楽かもしれないが、ドキュメントを読む癖を早めにつけておくとよいだろう。


HTTPサーバー

HTTPサーバはTCP/IP通信のサーバの一種だ。違いは、HTTPプロトコルの規則に従って通信を行うという点だ。

TCPサーバーの通信手順を以下に示す。


  1. socket(2)を実行してTCPソケットを作成する

  2. bind(2)を実行してソケットを登録する。

  3. listen(2)を実行して、ソケット接続を可能な状態にする。

  4. accept(2)を実行してクライアントの接続待ちをする。

  5. 接続後、send(2)でメッセージをクライアントに伝える。

  6. close(2)を実行してソケット通信を切断する。

上記の手順に従って作成したHTTPサーバのコードを下記に示す。


http_server.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main(){
int sock, ret, send_sock;
struct sockaddr_in addr;
struct sockaddr_in client;
socklen_t length;

sock = socket(AF_INET, SOCK_STREAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;

ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr) );

listen(sock, 5);
while(1) {
length = sizeof(client);
send_sock = accept(sock , (struct sockaddr *)&client, &length);
send(send_sock, "HTTP/1.0 200OK\r\n" "Content-Length:6\r\n"
"Content-Type:text/html\r\n" "\r\n" "HELLO\n", 66, 0);
close(send_sock);
}
close(sock);
}


gcc http_server.c

./a.out

実装したサーバを起動してみよう

適当なブラウザで127.0.0.1:8080にアクセスするとHELLOという文字が表示されていることを確認しよう。

HTTPサーバは80番ポートという認識をしている人がいるかもしれないが、80番以外でも通信できるのだ。


Wireshark


Wiresharkとは、ネットワークを流れるデータを捕縛して内容を解析・表示するプロトコルアナライザ(ネットワークアナライザ)の一つ。


Wiresharkでパケットを覗いてみよう。

以下のようにfilterをかけよう。

ip.addr == 127.0.0.1 and tcp.port == 8080 and http

スクリーンショット 2018-11-22 0.57.28.png

スクリーンショット 2018-11-22 0.58.44.png

HTTPサーバが正しく通信していることを確認できるだろう。


演習


  • Youtubeの通信をWiresharkで解析する

  • and httpを外して、3ウェイハンドシェイクを観察する


もっと深めたい人


参考文献

Linuxネットワークプログラミング


時間ができた時にやること