私はC言語のソケットで遊び始めました。bind()システムコールを使ってソケットにアドレスをバインドすると、addrlenパラメータを指定する必要があります。Cでソケットをバインドするときに、アドレスの長さのパラメータが必要なのはなぜですか?
ソケットでアドレスの長さが必要なのはなぜですか?
私はC言語のソケットで遊び始めました。bind()システムコールを使ってソケットにアドレスをバインドすると、addrlenパラメータを指定する必要があります。Cでソケットをバインドするときに、アドレスの長さのパラメータが必要なのはなぜですか?
ソケットでアドレスの長さが必要なのはなぜですか?
バインド機能(syscall)は、いくつかのタイプのアドレス(IPv4、IPv6、ブルートゥース、UNIXソケットなど)に対応しなければならない総称的な機能です。各アドレスタイプは、バインドのためにあなたが渡しているアドレスがそのサイズを渡すことでクリアされます。
bindはシステムコールです。syscallは、カーネルスペースとやりとりするためにユーザスペースで使用される単なるラッパー関数です。ソケットsyscalls経由でソケットを作成すると、呼び出しプロセスのファイル記述子テーブルにレコードが作成されます。レコード自体にソケットのタイプが含まれています。 バインドを呼び出してアドレスを渡すときは、アドレスをカーネルスペースにコピーする必要がありますが、アドレスの大きさはどれくらいですか? bind syscallはバインドしているソケットを認識しません。なぜなら、カーネルスペースとuserspaceのバインド関数で作成されたソケットレコードとそれぞれのsyscallは、必要なサイズを知らないからです。実際にはバインドはアドレスデータをカーネル空間にコピーし、カーネルに通知します。一方で
純粋C.
には、実行時の型チェックはので、この時点でバインドがアドレスを知っていないと、あなたがすべき存在しないため、バインドは、実行時にアドレス時間を決定することができませんでしたがアドレスのサイズを指定すると、アドレス構造は完全にカーネルスペースにコピーされます。
ソケットアドレスのいくつかの異なる種類が、これらは、それぞれの長さを渡すなど、独自のsockaddr_*
構造、AF_INET
用すなわちsockaddr_in
、AF_INET6
ため、
は、カーネルが経過していることを確認することができますしている
ありますデータはソケットの種類と一致しています。
以下のように長さが「あなたが持っている場合、クロスチェックのいくつかの並べ替えです処理しますAF_INETを宣言しましたが、使用しているアドレスはAF_INET6ですか? – giomanda
@Dai厳密にはそうは思いません - 宣言されたプロトコルファミリに必要なよりも小さな構造体を渡した場合、カーネルが不平を言うことを期待します – Alnitak
@giomanda:理論上、単一のアドレスでも長さが変わる可能性があります家族。覚えておいてください。このソケットインタフェースは、ネットワーキングの起源にまで遡ります。電話機は時代にはまったく共通していて、電話番号は確立された形式のネットワークアドレスでした。アドレスの長さが固定されたIPの成功は予期されておらず、IPv6では、アドレスの長さを固定しておくことは良い考えではないことが示されています。 – MSalters
システムコールは、例えば、それらが
全てでありますそれらのソケット記述の長さが異なっていてもよい。このため、対応する構造体の長さを指定する必要があります。
バインド(数sockfd、(sockaddr構造体の*)& serv_addr、はsizeof(serv_addr))
これは3つの引数、ソケットファイルディスクリプタ、をバインドされているアドレス、およびサイズを取りますがバインドされています
なぜソケットでアドレスの長さが必要ですか?
そのそれは例えば
を結合した制限は、私はそれが
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
error("ERROR on binding");
}
しかし、ソケットの作成時にすでにアドレスファミリを宣言しているので、どのアドレスを渡しているのか分かりませんか? – giomanda
@giomanda回答更新 –