Unix/Linuxドメインプロトコルを利用したクライアント-サーバ間のデータ送受信の様子を
パケット解析ツールWiresharkを使って、ダンプしてみる。
動作概要
サーバプロセス
1. サーバプロセスで、ソケットを作成、
2. ファイル UNIXSTR_PATH(=/tmp/unix.str)をソケットにバインド、
3. ソケットをクライアントからの接続を待ち(Listen)状態に設定 、
4. クライアントからの接続要求をacceptを発行して待つ。
5. 接続確立後、forkし、子プロセスを生成
6. リスニングソケットをクローズ
7. クライアントからのエコー要求を処理
クライアントプロセス
1. クライアントプロセスで、ソケットを作成
2. サーバプロセスへ接続要求(Connect)を発行
3. サーバへのエコー処理
実行環境
Ubuntu 12.04 LTS
gcc Version: 4.6.3
Unix/Linuxドメイン ストリームプロトコル echoサーバ
#include "unp.h"
int
main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_un cliaddr, servaddr;
void sig_chld(int);
listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
unlink(UNIXSTR_PATH);
bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path, UNIXSTR_PATH);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for ( ; ; ) {
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
if (errno == EINTR)
continue; /* back to for() */
else
err_sys("accept error");
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
str_echo(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
Unix/Linuxドメイン ストリームプロトコル echoクライアント
#include "unp.h"
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_un servaddr;
sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path, UNIXSTR_PATH);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd); /* do it all */
exit(0);
}
サーバプロセス、クライアントプロセスの順に起動
クライアントプロセスの端末で、文字列入力、エコーバックされる。
ダンプ結果
wiresharkで、パケット監視するインターフェースを"lo"(つまり、Localhost = 127.0.0.1)に設定して
キャプチャを試みたがパケット取得出来なかった。
つまり、TCP/IPソケット通信と同じAPIを利用出来るとしても、TCP/IPではないってことか...。
うーん、そしたら、Unix/Linuxドメインプロトコルのデータパケットのデバッグってどうするんだろー?