以下の API 呼び出しのシーケンスは、ソケットが非活動状態になったら、信号を使用してアプリケーショ ンにアラートする方法を示します。
1. socket() API が、端点を表すソケット記述子を戻します。ステートメントは、このソケットのために
AF_INET6 (インターネット・プロトコル バージョン 6) アドレス・ファミリーと TCP トランスポー
ト (SOCK_STREAM) を使用することも示します。
2. ソケット記述子が作成された後、bind() API が、ソケットの固有名を取得します。この例の場合、クラ イアント・アプリケーションはこのソケットに接続しないため、ポート番号は指定されません。このコ ードの断片は、accept() のようなブロック化 API を使用する、他のサーバー・プログラムで使用できま す。
3. listen() API は、クライアントの接続要求を受け入れる態勢を示しています。 listen() API が発行された
後、アラームが 5 秒後に発生するよう設定されます。このアラームまたは信号は、accept() 呼び出しの ブロックが発生すると、警告を出します。
4. accept() API は、クライアント接続要求を受け入れます。この呼び出しは通常、無期限にブロックしま
すが、アラームが設定されているため、呼び出しは 5 秒間だけブロックされます。アラームが止まる と、accept 呼び出しは -1 を戻して終了し、EINTR という errno 値を戻します。
5. close() API が、オープンしているソケット記述子をすべて終了させます。
注: この例の使用をもって、213ページの『コードに関するライセンス情報および特記事項』の条件に同意 したものとします。
/******************************************************************/
/* Example shows how to set alarms for blocking socket APIs */
/******************************************************************/
/******************************************************************/
/* Include files */
/******************************************************************/
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
/******************************************************************/
/* Signal catcher routine. This routine will be called when the */
/* signal occurs. */
/******************************************************************/
void catcher(int sig) {
printf(" Signal catcher called for signal %d\n", sig);
}
/******************************************************************/
/* Main program */
/******************************************************************/
int main(int argc, char *argv[]) {
struct sigaction sact;
struct sockaddr_in6 addr;
time_t t;
int sd, rc;
/******************************************************************/
/* Create an AF_INET6, SOCK_STREAM socket */
/******************************************************************/
printf("Create a TCP socket\n");
sd = socket(AF_INET6, SOCK_STREAM, 0);
if (sd == -1) {
perror(" socket failed");
return(-1);
}
/******************************************************************/
/* Bind the socket. A port number was not specified because */
/* we are not going to ever connect to this socket. */
/******************************************************************/
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
printf("Bind the socket\n");
rc = bind(sd, (struct sockaddr *)&addr, sizeof(addr));
if (rc != 0) {
perror(" bind failed");
close(sd);
return(-2);
}
/******************************************************************/
/* Perform a listen on the socket. */
/******************************************************************/
printf("Set the listen backlog\n");
rc = listen(sd, 5);
if (rc != 0) {
perror(" listen failed");
close(sd);
return(-3);
}
/******************************************************************/
/* Set up an alarm that will go off in 5 seconds. */
/******************************************************************/
printf("\nSet an alarm to go off in 5 seconds. This alarm will cause the\n");
printf("blocked accept() to return a -1 and an errno value of EINTR.\n\n");
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = catcher;
sigaction(SIGALRM, &sact, NULL);
alarm(5);
/******************************************************************/
/* Display the current time when the alarm was set */
/******************************************************************/
time(&t);
printf("Before accept(), time is %s", ctime(&t));
/******************************************************************/
/* Call accept. This call will normally block indefinitely, */
/* but because we have an alarm set, it will only block for */
/* 5 seconds. When the alarm goes off, the accept call will */
/* complete with -1 and an errno value of EINTR. */
/******************************************************************/
errno = 0;
printf(" Wait for an incoming connection to arrive\n");
rc = accept(sd, NULL, NULL);
printf(" accept() completed. rc = %d, errno = %d\n", rc, errno);
if (rc >= 0) {
printf(" Incoming connection was received\n");
close(rc);
} else {
perror(" errno string");
}
/******************************************************************/
/* Show what time it was when the alarm went off */
/******************************************************************/
time(&t);
printf("After accept(), time is %s\n", ctime(&t));
close(sd);
return(0);
}
関連概念:
62ページの『信号』
アプリケーション・プログラムは、アプリケーションがかかわる条件が発生するときに、非同期に通知する ことを要求 (システムが信号を送信するように要求) できます。
46ページの『非同期入出力』
非同期入出力 API は、スレッド化されたクライアント/サーバーのモデルに、高度な同時入出力およびメモ リー効率のよい入出力を実行するための方法を提供します。
関連資料:
72ページの『バークレー・ソフトウェア・ディストリビューションとの互換性』
ソケットはバークレー・ソフトウェア・ディストリビューション (BSD) のインターフェースです。
122ページの『例: 非同期入出力 API の使用』
アプリケーションは、QsoCreateIOCompletionPort() API を使用して入出力完了ポートを作成します。この API は、非同期入出力要求の完了をスケジュールして待機するために使用できるハンドルを戻します。
関連情報:
accept()--Wait for Connection Request and Make Connection API listen()--Invite Incoming Connections Requests API
close()--Close File or Socket Descriptor API socket()--Create Socket API
bind()--Set Local Address for Socket API
例 : AF_INET を使用するマルチキャスティングの使用
IP マルチキャスティングを使用すると、アプリケーションがネットワークにあるホストのグループが受信 可能な、単一の IP データグラムを送信できるようになります。
注: この例の使用をもって、213ページの『コードに関するライセンス情報および特記事項』の条件に同意 したものとします。
グループにあるホストは、単一のサブネットに常駐する場合も、マルチキャスト機能のあるルーターに接続 する異なるサブネットに位置する場合もあります。ホストはいつでもグループに結合したり分離したりでき ます。ホスト・グループでのメンバーの位置や数については、制限はありません。 224.0.0.1 から
239.255.255.255 の範囲のクラス D の IP アドレスは、ホスト・グループを識別します。
アプリケーション・プログラムは、socket() API およびコネクションレス型 SOCK_DGRAM タイプ・ソケ ットを使用することにより、マルチキャスト・データグラムを送受信できます。マルチキャストは、1 対多 の伝送方式です。マルチキャストには、タイプ SOCK_STREAM のコネクション型ソケットを使用するこ とはできません。タイプ SOCK_DGRAM のソケットが作成されると、アプリケーションは setsockopt() API を使用して、このソケットに関連するマルチキャスト特性を制御することができます。setsockopt() API は、以下の IPPROTO_IP レベル・フラグを受け取ります。
v IP_ADD_MEMBERSHIP: 指定されたマルチキャスト・グループを結合させます。
v IP_DROP_MEMBERSHIP: 指定されたマルチキャスト・グループを外れます。
v IP_MULTICAST_IF: 発信マルチキャスト・データグラムが送信されるインターフェースを設定します。
v IP_MULTICAST_TTL: 発信マルチキャスト・データグラムについて IP ヘッダーの存続時間 (TTL) を設
定します。
v IP_MULTICAST_LOOP: 発信マルチキャスト・データグラムのコピーがマルチキャスト・グループのメ
ンバーであるかぎり、そのコピーが送信しているホストに送達されるようにするかどうかを指定しま す。
注: IBM i ソケットは、AF_INET アドレス・ファミリーの IP マルチキャスティングをサポートします。