Unix/Linuxドメインプロトコルを利用したクライアント-サーバ間のデータ送受信を確認したが、
下記の状況下での動作について、検証してみる。
検証ケース
ドメインプロトコルを利用したサーバが終了時に、
ウェルノウンパス UNIXSTR_PATh(=/tmp/unix.str)をunlinkしない。
その後、クライアントがサーバにconnectしようとした場合、何が起きるか?
動作概要
サーバプロセス
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);
}
サーバプロセスを起動し、ウェルノウンパスをバインド、その後、サーバプロセスをkillで終了
クライアントプロセスを起動し、ウェルノウンパスへconnect実施
実行結果
$ ./unixstrserv01 &
サーバプロセスを起動した状態で、ウェルノウンパス(=/tmp/unix.str)を開いているプロセス情報を確認
$ lsof /tmp/unix.str
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unixstrse 6956 k3ijo 3u unix 0x00000000 0t0 69127 /tmp/unix.str
その後、サーバプロセスをkillする。
$ kill 6956
ウェルノウンパス(=/tmp/unix.str)を開いているプロセス情報を確認
$ lsof /tmp/unix.str
[1]+ Terminated ./unixstrserv01
その後、クライアントプロセスを起動し、ウェルノウンパスへ接続要求を出す。
$ ./unixstrcli01
connect error: Connection refused
Connectが拒絶される。