2011-07-25 3 views
3

Unix Domain Socketsに関するbind()関数の理解に問題があります。Cプログラミング - 理解するbind()

address.sun_family = AF_UNIX; 
addrlen = sizeof(address.sun_family) + strlen(SOCK_PATH); 
. 
. 
. 
bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) 

私は現在理解したように、これは)(ソケットを使用して作成されました(プロセスの名前空間にあります)socket_fdをとり、ソケットにアドレスに含まれるアドレス情報を「適用」。基本的に他のプロセスが使用できるように作成しています....私はそれが正しいと思います。

私が分からないことは、addrlen引数の必要性です。これは、先頭/末尾のヌルバイトを持たないアドレス構造体の長さです。正しい?この引数は、bind()にアドレスから読み出すバイト数を指示するために必要ですか?

あなたの洞察に感謝します!あなたのaddrlenはこのように設定されている理由

答えて

1

わからないが、通常の/正しい方法ではありません:

memset(&addr, 0, sizeof(struct sockaddr_un)); 
         /* Clear structure */ 
    addr.sun_family = AF_UNIX; 
    strncpy(addr.sun_path, MY_SOCK_PATH, 
      sizeof(addr.sun_path) - 1); 

    if (bind(sfd, (struct sockaddr *) &addr, 
      sizeof(struct sockaddr_un)) == -1) { 
     perror("bind"); 
     exit(EXIT_FAILURE); 
    } 

ノートのsizeofの使用は()、

+0

大丈夫ですが、必然的なaccept()関数の第3引数としてaddrlenが必要です。だから私はbind()とaccept()の両方でそれを使わないのですか? –

+0

値は同じです(設定しても問題ありませんが、同じソケット構造を使用している限り、正しく実行されます(正しく行われていると 'addrlen = sizeof(struct sockaddr_un);') – KevinDTimm

+0

'accept'の場合、addrlenは入力と出力の両方です。あなたが渡しているバッファのサイズを指定します。カーネルはあなたに接続しているsockaddrの大きさを返します。 –

2

を期待strlen関数/ addrlenは決して簡単に言えば、バインドはシステムに言った:okay, from now on, any packet with destination {address->sun_addr} should be forwarded to my socket_fd, so I can read them

addrlen引数は、(異なるサイズの)異なるタイプの構造体を渡すことができるため、構造体のサイズを指定します。例えば、struct sockaddr_un*,struct sockaddr_in*struct sockaddr*の代わりに「共通」構造体が渡されるため、bind実際のタイプの構造体を認識しません。これが長さを渡さなければならない理由です。

PS:私はあなたがプロセスのアドレス空間ではなくプロセス名前空間を意味確信しています。

0

また、私はまだ...

、私は非常に間違っている可能性があり、または私は正しい方向にあるかもしれないので、多分、私をここにもたらしたものをthatsの学習、私はとても疲れも、同様に学ぶのを助ける私の理解を説明しています

IPv4アドレスとIPv6アドレスは異なるプロトコルのアドレスと異なる長さであるため、Apple TalkやHam RadioプロトコルなどのプロトコルではIPv4スタイルのアドレスに似たアドレスを使用するとは限りませんバイト、オクテットと呼ばれ、 "。"で区切られていると思います。

あなたは「はsizeof(構造体のsockaddr_in)」を呼び出すときにあなたはstruct sockaddr_unとして(はsizeofの「はsizeof(構造体のsockaddr_in6)」とは異なるだろうこれは、バイトのsockaddr_in構造体の数はで構成されている「INT」に渡しています)。 sockaddr_inはinetまたはIPv4、* _in6はinet6またはIPv6、* _unはUnixドメインソケット用です。私は、Unixドメインソケットアドレスは、ローカルプロセス通信にしか使用できないファイルパスだと考えています。したがって、関数/メソッドは、/ home/user/Pictures/socketのようなソケットファイルがどこにあるかを知る必要があるので、それをローカルポート、したがってstrncopyおよびsun_pathビジネスにバインドすることができます。これはinet/6ソケットにも適用されるかもしれません。 (Windows上でC/C++を学ぶことは、私がこれまで行ってきた自殺に最も近いものでした)。

"sizeof(struct sockaddr_un)"を介して渡されるintは、実際の実装コード内で実行モードを決定するために使用できます。もしarg [2] = Nならこれを実行し、そうでなければarg [2] = Mならそれを行うでしょうか?多分...

ソケットのマニュアルを読むと、この例でaddrlenではなくsizeof()が使用されていることがわかります。

注:プロトコルのアドレス構造のバイト数を達成する場合、使用する構造体に実際に有用なデータが含まれているかどうかは関係ありません。そのサイズが必要なだけなので、構造体がパラメータ内でインスタンス化されます新しく作成されたstructに "sizeof()"を使用すると、必要なintが返され、それが第3引数の引数として使用されます。

関連する問題