/*************************************************/
/* 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);
}
v sendmsg() サーバーおよび rcvmsg() ワーカー。『例: sendmsg() および recvmsg() で使用するサーバー・
プログラム』を参照してください。
v 複数の accept() 設計。『例: 複数の accept() ワーカー・ジョブのプールを作成するためのサーバー・プ
ログラム』を参照してください。
v 非ブロッキング入出力および select() 設計。『例: 非ブロッキング入出力および select()』を参照してく ださい。
v IPv4 クライアントまたは IPv6 クライアントからの接続を受け入れるサーバー。『例: IPv6 クライアン トと IPv4 クライアントの両方から接続を受け入れる』を参照してください。
ソケットのイベントのフロー
:
汎用クライアント次のプログラム例は、以下の API 呼び出しのシーケンスを使用します。
1. socket() API が、端点を表すソケット記述子を戻します。ステートメントは、このソケットのために
INET (インターネット・プロトコル) アドレス・ファミリーと TCP トランスポート (SOCK_STREAM)
を使用することも示します。
2. ソケット記述子を受信したら、connect() API を使用して、サーバーへの接続を確立します。
3. send() API が、データ・バッファーをワーカー・ジョブに送信します。
4. recv() API が、ワーカー・ジョブからデータ・バッファーを受信します。
5. close() API が、オープンしているソケット記述子をすべてクローズします。
注: この例の使用をもって、213ページの『コードに関するライセンス情報および特記事項』の条件に同意 したものとします。
/**************************************************************************/
/* Generic client example is used with connection-oriented server designs */
/**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 12345 main (int argc, char *argv[]) {
int len, rc;
int sockfd;
char send_buf[80];
char recv_buf[80];
struct sockaddr_in6 addr;
/*************************************************/
/* Create an AF_INET6 stream socket */
/*************************************************/
sockfd = socket(AF_INET6, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
exit(-1);
}
/*************************************************/
/* Initialize the socket address structure */
/*************************************************/
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);
/*************************************************/
/* Connect to the server */
/*************************************************/
rc = connect(sockfd,
(struct sockaddr *)&addr, sizeof(struct sockaddr_in6));
if (rc < 0) {
perror("connect");
close(sockfd);
exit(-1);
}
printf("Connect completed.\n");
/*************************************************/
/* Enter data buffer that is to be sent */
/*************************************************/
printf("Enter message to be sent:\n");
gets(send_buf);
/*************************************************/
/* Send data buffer to the worker job */
/*************************************************/
len = send(sockfd, send_buf, strlen(send_buf) + 1, 0);
if (len != strlen(send_buf) + 1) {
perror("send");
close(sockfd);
exit(-1);
}
printf("%d bytes sent\n", len);
/*************************************************/
/* Receive data buffer from the worker job */
/*************************************************/
len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);
if (len != strlen(send_buf) + 1) {
perror("recv");
close(sockfd);
exit(-1);
}
printf("%d bytes received\n", len);
/*************************************************/
/* Close down the socket */
/*************************************************/
close(sockfd);
}
関連資料:
90ページの『例: IPv4 または IPv6 クライアント』
このサンプル・プログラムは、IPv4 クライアントまたは IPv6 クライアントのどちらかからの要求を受け 入れるサーバー・アプリケーションと一緒に使用できます。
96ページの『例: コネクション型設計』
さまざまな方法で、システム上のコネクション型ソケット・サーバーを設計することができます。これらの プログラム例を使用して、独自のコネクション型設計を作成することができます。
98ページの『例: 反復サーバー・プログラムの作成』
この例では、すべての着信接続を処理する単一のサーバー・ジョブを作成する方法を示します。accept() API が完了すると、サーバーがトランザクション全体を処理します。
107ページの『例: プロセス間での記述子の受け渡し』
以下の例では、sendmsg() および recvmsg() API を使用して着信接続を処理するサーバー・プログラムの設 計方法を示します。
109ページの『例: sendmsg() および recvmsg() で使用するサーバー・プログラム』
以下の例では、sendmsg() API を使用してワーカー・ジョブのプールを作成する方法を示しています。
114ページの『例: 複数の accept() API を使用した着信要求の処理』
以下の例では、複数の accept() モデルを使用するサーバー・プログラムを設計して、着信接続要求をハン ドリングする方法を示しています。
116ページの『例: 複数の accept() ワーカー・ジョブのプールを作成するためのサーバー・プログラム』
以下の例では、複数の accept() モデルを使用して、ワーカー・ジョブをプールを作成する方法を示してい ます。
101ページの『例: spawn() API を使用した子プロセスの作成』
この例では、サーバー・プログラムが spawn() API を使用して、親からソケット記述子を継承する子プロ セスを作成する方法を示しています。
85ページの『例: IPv6 クライアントと IPv4 クライアントの両方から接続を受け入れる』
このプログラム例では、IPv4 (AF_INET アドレス・ファミリーを使用するソケット・アプリケーション)
および IPv6 (AF_INET6 アドレス・ファミリーを使用するアプリケーション) の両方からの要求を受け入
れるサーバー/クライアント・モデルを作成する方法を示します。