• 検索結果がありません。

例: 複数の accept() API を使用した着信要求の処理

ドキュメント内 rzab6pdf.ps (ページ 120-125)

len = rc;

rc = send(pass_sd, buffer, len, 0);

if (rc <= 0) {

perror("send() failed");

close(worker_sd);

close(pass_sd);

exit(-1);

}

/*************************************************/

/* Close down the descriptors */

/*************************************************/

close(worker_sd);

close(pass_sd);

}

ソケットのイベントのフロー: 複数の

accept()

ワーカー・ジョブのプールを作成するサーバー 以下のソケット呼び出しのシーケンスは、図の説明となっています。これはまた、サーバーとワーカーの例 の関係の説明ともなっています。それぞれのフローには、特定の API の使用上の注意へのリンクが含まれ ています。特定の API の使用に関する詳細情報は、これらのリンクを使用して参照してください。最初の 例は、以下のソケット呼び出しを使用して子プロセスを作成します。

1. socket() API が、端点を表すソケット記述子を戻します。ステートメントは、このソケットのために

INET (インターネット・プロトコル) アドレス・ファミリーと TCP トランスポート (SOCK_STREAM)

を使用することも示します。

2. ソケット記述子が作成された後、bind() API が、ソケットの固有名を取得します。

3. listen() API により、サーバーが着信クライアント接続を受け入れられるようになります。

4. spawn() API が、各ワーカー・ジョブを作成します。

5. この例では、最初の close() API が listen ソケットをクローズします。

ソケットのイベントのフロー

:

複数の

accept()

を使用するワーカー・ジョブ 2 番目の例は、以下の API 呼び出しのシーケンスを使用します。

1. サーバーがワーカー・ジョブを spawn した後、このワーカー・ジョブに listen ソケット記述子が、コ マンド行パラメーターとして渡されます。 accept() API が、着信クライアント接続を待機します。

2. recv() API が、クライアントからデータを受信します。

3. send() API が、クライアントにデータを送り返します。

4. close() API が、ワーカー・ジョブを終了します。

関連資料:

119ページの『例: 汎用クライアント』

この例には、共通クライアント・ジョブのコードが含まれています。クライアント・ジョブは、

socket()、connect()、send()、recv()、および close() を実行します。

関連情報:

spawn()

bind()--Set Local Address for Socket API socket()--Create Socket API

listen()--Invite Incoming Connections Requests API close()--Close File or Socket Descriptor API

accept()--Wait for Connection Request and Make Connection API send()--Send Data API

recv()--Receive Data API

例: 複数の accept() ワーカー・ジョブのプールを作成するためのサーバー・プログラム:

以下の例では、複数の accept() モデルを使用して、ワーカー・ジョブをプールを作成する方法を示してい ます。

注: この例の使用をもって、213ページの『コードに関するライセンス情報および特記事項』の条件に同意 したものとします。

/*****************************************************************************/

/* Server example creates a pool of worker jobs with multiple accept() calls */

/*****************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <spawn.h>

#define SERVER_PORT 12345 main (int argc, char *argv[]) {

int i, num, pid, rc, on = 1;

int listen_sd, accept_sd;

int spawn_fdmap[1];

char *spawn_argv[1];

char *spawn_envp[1];

struct inheritance inherit;

struct sockaddr_in6 addr;

/*************************************************/

/* If an argument was specified, use it to */

/* control the number of incoming connections */

/*************************************************/

if (argc >= 2)

num = atoi(argv[1]);

else num = 1;

/*************************************************/

/* Create an AF_INET6 stream socket to receive */

/* incoming connections on */

/*************************************************/

listen_sd = socket(AF_INET6, SOCK_STREAM, 0);

if (listen_sd < 0) {

perror("socket() failed");

exit(-1);

}

/*************************************************/

/* Allow socket descriptor to be reuseable */

/*************************************************/

rc = setsockopt(listen_sd,

SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));

if (rc < 0) {

perror("setsockopt() failed");

close(listen_sd);

exit(-1);

}

/*************************************************/

/* Bind the socket */

/*************************************************/

memset(&addr, 0, sizeof(addr));

addr.sin6_family = AF_INET6;

memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));

addr.sin6_port = htons(SERVER_PORT);

rc = bind(listen_sd,

(struct sockaddr *)&addr, sizeof(addr));

if (rc < 0) {

perror("bind() failed");

close(listen_sd);

exit(-1);

}

/*************************************************/

/* Set the listen back log */

/*************************************************/

rc = listen(listen_sd, 5);

if (rc < 0) {

perror("listen() failed");

close(listen_sd);

exit(-1);

}

/*************************************************/

/* Initialize parameters before entering for loop */

/* */

/* The listen socket descriptor is mapped to */

/* descriptor 0 in the child program. */

/*************************************************/

memset(&inherit, 0, sizeof(inherit));

spawn_argv[0] = NULL;

spawn_envp[0] = NULL;

spawn_fdmap[0] = listen_sd;

/*************************************************/

/* Create each of the worker jobs */

/*************************************************/

printf("Creating worker jobs...\n");

for (i=0; i < num; i++) {

pid = spawn("/QSYS.LIB/QGPL.LIB/WRKR3.PGM", 1, spawn_fdmap, &inherit, spawn_argv, spawn_envp);

if (pid < 0) {

perror("spawn() failed");

close(listen_sd);

exit(-1);

}

printf(" Worker = %d\n", pid);

}

/*************************************************/

/* Inform the user that the server is ready */

/*************************************************/

printf("The server is ready\n");

/*************************************************/

/* Close down the listening socket */

/*************************************************/

close(listen_sd);

}

関連資料:

119ページの『例: 汎用クライアント』

この例には、共通クライアント・ジョブのコードが含まれています。クライアント・ジョブは、

socket()、connect()、send()、recv()、および close() を実行します。

例: 複数の accept() 用のワーカー・ジョブ:

以下の例は、複数の accept() API がワーカー・ジョブを受信し、accept() サーバーを呼び出す方法につい て示します。

注: この例の使用をもって、213ページの『コードに関するライセンス情報および特記事項』の条件に同意 したものとします。

/**************************************************************************/

/* Worker job uses multiple accept() to handle incoming client connections*/

/**************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

main (int argc, char *argv[]) {

int rc, len;

int listen_sd, accept_sd;

char buffer[80];

/*************************************************/

/* The listen socket descriptor is passed to */

/* this worker job as a command line parameter */

/*************************************************/

listen_sd = 0;

/*************************************************/

/* Wait for an incoming connection */

/*************************************************/

printf("Waiting on accept()\n");

accept_sd = accept(listen_sd, NULL, NULL);

if (accept_sd < 0) {

perror("accept() failed");

close(listen_sd);

exit(-1);

}

printf("Accept completed successfully\n");

/*************************************************/

/* Receive a message from the client */

/*************************************************/

printf("Wait for client to send us a message\n");

rc = recv(accept_sd, buffer, sizeof(buffer), 0);

if (rc <= 0) {

perror("recv() failed");

close(listen_sd);

close(accept_sd);

exit(-1);

}

printf("<%s>\n", buffer);

/*************************************************/

/* Echo the data back to the client */

/*************************************************/

printf("Echo it back\n");

len = rc;

rc = send(accept_sd, buffer, len, 0);

if (rc <= 0) {

perror("send() failed");

close(listen_sd);

close(accept_sd);

exit(-1);

}

/*************************************************/

/* Close down the descriptors */

/*************************************************/

close(listen_sd);

close(accept_sd);

}

ドキュメント内 rzab6pdf.ps (ページ 120-125)