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

例: spawn() API を使用した子プロセスの作成

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

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 incoming connection */

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

close(accept_sd);

}

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

/* Close down the listen socket */

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

close(listen_sd);

}

関連資料:

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

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

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

関連情報:

recv()--Receive Data API

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

listen()--Invite Incoming Connections Requests API

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

close()--Close File or Socket Descriptor API

以下の図は、spawn() サーバー設計が使用される場合に、サーバー、ワーカー、およびクライアント・ジョ ブが対話する方法を示しています。

ソケットのイベントのフロー: spawn() を使用して要求を受け入れ処理するサーバー

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

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

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

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

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

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

4. サーバーは、着信接続要求を受け入れるために accept() API を使用します。 accept() 呼び出しは、着 信接続を待機して、無期限にブロックします。

5. spawn() API が、着信要求を処理するワーカー・ジョブのパラメーターを初期設定します。この例で は、新規接続のソケット記述子が子プログラムの記述子 0 にマップされます。

6. この例では、最初の close() API が listen ソケット記述子をクローズします。 2 番目の close () 呼び 出しは、受け入れたソケットを終了します。

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

: spawn()

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

1. サーバーで spawn() API が呼び出されると、recv() API が着信接続からデータを受信します。

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

3. close() API が、spawn されたワーカー・ジョブを終了します。

関連資料:

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

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

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

関連情報:

spawn()

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

listen()--Invite Incoming Connections Requests API

accept()--Wait for Connection Request and Make Connection API close()--Close File or Socket Descriptor API

send()--Send Data API recv()--Receive Data API

例: spawn() を使用するサーバーの作成:

以下の例では、spawn() API を使用して、親プロセスからソケット記述子を継承する子プロセスを作成する 方法を示しています。

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

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

/* Application creates an child process using spawn(). */

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

#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;

addr.sin6_port = htons(SERVER_PORT);

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

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);

}

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

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

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

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

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

/* Go through the loop once for each connection */

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

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

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

/* Wait for an incoming connection */

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

printf("Interation: %d\n", i+1);

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");

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

/* Initialize the spawn parameters */

/* */

/* The socket descriptor for the new */

/* connection is mapped over to descriptor 0 */

/* in the child program. */

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

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

spawn_argv[0] = NULL;

spawn_envp[0] = NULL;

spawn_fdmap[0] = accept_sd;

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

/* Create the worker job */

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

printf(" creating worker job\n");

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

if (pid < 0) {

perror("spawn() failed");

close(listen_sd);

close(accept_sd);

exit(-1);

}

printf(" spawn completed successfully\n");

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

/* Close down the incoming connection since */

/* it has been given to a worker to handle */

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

close(accept_sd);

}

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

/* Close down the listen socket */

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

close(listen_sd);

}

関連資料:

106ページの『例: ワーカー・ジョブがデータ・バッファーを受信できるようにする』

この例には、ワーカー・ジョブがクライアント・ジョブからデータ・バッファーを受け取るようにし、これ をそのまま戻すためのコードが含まれています。

例: ワーカー・ジョブがデータ・バッファーを受信できるようにする:

この例には、ワーカー・ジョブがクライアント・ジョブからデータ・バッファーを受け取るようにし、これ をそのまま戻すためのコードが含まれています。

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

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

/* Worker job that receives and echoes back a data buffer to a client */

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

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

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

int rc, len;

int sockfd;

char buffer[80];

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

/* The descriptor for the incoming connection is */

/* passed to this worker job as a descriptor 0. */

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

sockfd = 0;

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

/* Receive a message from the client */

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

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

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

if (rc <= 0) {

perror("recv() failed");

close(sockfd);

exit(-1);

}

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

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

/* Echo the data back to the client */

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

printf("Echo it back\n");

len = rc;

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

if (rc <= 0) {

perror("send() failed");

close(sockfd);

exit(-1);

}

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

/* Close down the incoming connection */

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

close(sockfd);

}

関連資料:

103ページの『例: spawn() を使用するサーバーの作成』

以下の例では、spawn() API を使用して、親プロセスからソケット記述子を継承する子プロセスを作成する 方法を示しています。

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