JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
プログラミングインタフェースガイド     Oracle Solaris 10 1/13 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  メモリーと CPU の管理

2.  リモート共有メモリー API (Solaris クラスタ用)

3.  セッション記述プロトコル API

4.  プロセススケジューラ

5.  近傍性グループ API

6.  入出力インタフェース

7.  プロセス間通信

8.  ソケットインタフェース

SunOS 4 のバイナリ互換性

ソケットの概要

ソケットライブラリ

ソケットタイプ

インタフェースセット

ソケットの基本的な使用

ソケットの作成

ローカル名のバインド

コネクションの確立

コネクションエラー

データ転送

ソケットを閉じる

ストリームソケットのコネクション

入出力の多重化

データグラムソケット

標準ルーチン

ホスト名とサービス名

ホスト名 - hostent

ネットワーク名 - netent

プロトコル名 - protoent

サービス名 - servent

その他のルーチン

クライアントサーバープログラム

ソケットとサービス

ソケットとクライアント

コネクションレス型のサーバー

ソケットの拡張機能

帯域外データ

非ブロックソケット

非同期ソケット入出力

割り込み方式のソケット入出力

シグナルとプロセスグループ ID

特定のプロトコルの選択

アドレスのバインド

ソケットオプション

inetd デーモン

ブロードキャストとネットワーク構成の判断

マルチキャストの使用

IPv4 マルチキャストデータグラムの送信

IPv4 マルチキャストデータグラムの受信

IPv6 マルチキャストデータグラムの送信

IPv6 マルチキャストデータグラムの受信

Stream Control Transmission Protocol (SCTP)

SCTP スタックの実装

SCTP ソケットインタフェース

sctp_bindx()

sctp_opt_info()

sctp_recvmsg()

sctp_sendmsg()

sctp_send()

分岐関連付け

sctp_getpaddrs()

sctp_freepaddrs()

sctp_getladdrs()

sctp_freeladdrs()

SCTP を使用したコーディング例

9.  XTI と TLI を使用したプログラミング

10.  パケットフィルタリングフック

11.  トランスポート選択と名前からアドレスへのマッピング

12.  リアルタイムプログラミングと管理

13.  Solaris ABI と ABI ツール

A.  UNIX ドメインソケット

索引

データグラムソケット

データグラムソケットは、コネクションの確立を要求せずに、対称型データ交換インタフェースを提供します。各メッセージには着信先アドレスが含まれます。次の図では、サーバーとクライアント間の通信の流れを示します。

次の図において、サーバー側の bind(3SOCKET) 手順は省略できます。

図 8-2 データグラムソケットを使用したコネクションレス型の通信

image:この図はクライアントとサーバー間のデータフローを示します。sendto と recvfrom の関数を使用します。

「ソケットの作成」で説明しているように、データグラムソケットを作成します。特定のローカルアドレスが必要な場合、bind(3SOCKET) 操作を最初のデータ伝送よりも先に行う必要があります。それ以外の場合、データが最初に送信される際にシステムがローカルアドレスまたはポートを設定します。データを送信するには、sendto(3SOCKET) を使用します。

sendto(s, buf, buflen, flags, (struct sockaddr *) &to, tolen);

sbufbuflen、および flags パラメータは、コネクション型のソケットの場合と同じです。totolen の値は、意図するメッセージ受信者のアドレスを示します。ローカルにエラー条件 (到達できないネットワークなど) が検出されると、-1 が返され、errno にエラー番号が設定されます。

recvfrom(s, buf, buflen, flags, (struct sockaddr *) &from, &fromlen);

データグラムソケット上でメッセージを受信するには、recvfrom(3SOCKET) を使用します。呼び出しの前に、fromlenfrom バッファーのサイズに設定されます。fromlen にはデータグラムの配信元であるアドレスのサイズが設定されて返されます。

データグラムソケットは connect(3SOCKET) 呼び出しを使用して、ソケットを特定の着信先アドレスに関連付けることもできます。これにより、ソケットは send(3SOCKET) 呼び出しを使用できます。着信先アドレスが明示的に指定されていないソケット上に送信されるデータはすべて、接続されたピアにアドレス指定されます。そして、そのピアから受信されるデータだけが配信されます。1 つのソケットに一度に接続できるのは、接続された 1 つのアドレスだけです。2 番目の connect(3SOCKET) 呼び出しは、着信先アドレスを変更します。データグラムソケット上のコネクション要求は、すぐに返されます。システムは、ピアのアドレスを記録します。accept(3SOCKET)listen(3SOCKET) はデータグラムソケットでは使用されません。

データグラムソケットが接続されている間、前の send(3SOCKET) 呼び出しからのエラーは非同期に返すことができます。ソケットはこれらのエラーを後続の操作で報告できます。また、getsockopt(3SOCKET) のオプションである SO_ERROR を使用して、エラーステータスを問い合わせることもできます。

次のコードに、ソケットの作成、名前のバインド、ソケットへのメッセージ送信によって、インターネット呼び出しを送信する例を示します。

例 8-5 インターネットファミリデータグラムの送信

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define DATA "The sea is calm, the tide is full . . ."   
/*
 * Here I send a datagram to a receiver whose name I get from
 * the command line arguments. The form of the command line is:
 * dgramsend hostname portnumber
 */
main(int argc, char *argv[])
{
    int sock, errnum;
    struct sockaddr_in6 name;
    struct hostent *hp;
    /* Create socket on which to send. */
    sock = socket(AF_INET6,SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("opening datagram socket");
        exit(1);
    }
    /*
     * Construct name, with no wildcards, of the socket to ``send''
     * to. getinodebyname returns a structure including the network
     * address of the specified host. The port number is taken from
     * the command line.
     */
    hp = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT, &errnum);
    if (hp == (struct hostent *) 0) {
        fprintf(stderr, "%s: unknown host\n", argv[1]);
        exit(2);
    }
    bzero (&name, sizeof (name));
    memcpy((char *) &name.sin6_addr, (char *) hp->h_addr,
       hp->h_length);
    name.sin6_family = AF_INET6;
    name.sin6_port = htons(atoi(argv[2]));
    /* Send message. */
    if (sendto(sock,DATA, sizeof DATA ,0,
        (struct sockaddr *) &name,sizeof name) == -1)
        perror("sending datagram message");
    close(sock);
    exit(0);
}

次のコードに、ソケットの作成、名前のバインド、ソケットからのメッセージ読み取りによって、インターネット呼び出しを読み取る例を示します。

例 8-6 インターネットファミリデータグラムの読み取り

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
/*
 * This program creates a datagram socket, binds a name to it, then
 * reads from the socket.
 */
 main()
{
    int sock, length;
    struct sockaddr_in6 name;
    char buf[1024];
    /* Create socket from which to read. */
    sock = socket(AF_INET6, SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("opening datagram socket");
        exit(1);
    }
    /* Create name with wildcards. */
    bzero (&name, sizeof (name));
    name.sin6_family = AF_INET6;
    name.sin6_addr = in6addr_any;
    name.sin6_port = 0;
    if (bind (sock, (struct sockaddr *)&name, sizeof (name)) == -1) {
        perror("binding datagram socket");
        exit(1);
    }
    /* Find assigned port value and print it out. */
    length = sizeof(name);
    if (getsockname(sock,(struct sockaddr *) &name, &length)
            == -1) {
        perror("getting socket name");
        exit(1);
    }
    printf("Socket port #%d\n", ntohs(name.sin6_port));
    /* Read from the socket. */
    if (read(sock, buf, 1024) == -1 )
        perror("receiving datagram packet");
    /* Assumes the data is printable */
    printf("-->%s\n", buf);
    close(sock);
    exit(0);
}