1

アプリでマルチキャスト ポートをバインドしようとしています。以前はコードは常に機能していましたが、このサーバーでは (常にではありませんが、しばしば) 失敗します...

エラー メッセージは ですAddress already in use。複数のアプリケーションから (同じアプリケーションからでも) 同じアドレスをバインドできるため、よくわかりません...

何が原因でしょうか? 誰かがそれを要求することはわかっているので、コードは次のとおりです。

int fd = socket(PF_INET, SOCK_DGRAM, 0);
/* yes, that's a valid socket, verified.... */

u_int val = 1;
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
    perror("Reusing ADDR failed");
    exit(1);
}

struct sockaddr_in saddr;
saddr.sin_family = PF_INET;
saddr.sin_addr.s_addr = inet_addr(multicast_group_ip);
saddr.sin_port = htons(port);
/* yes, valid multicast ip address and port, verified */

if(bind(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) == -1)
    //FAILS....
4

2 に答える 2

3

実際には、複数のデータグラム ソケットを同じマルチキャスト グループとポートにバインドできます。ただし、これらのソケットはすべて SO_REUSEADDR オプションを設定する必要があります。あなたのコードに基づいてこれを行っているようですが、そのオプションを設定せずにソケットを同じマルチキャストグループとポートにバインドした別のプロセスがサーバーにあるようです。解決策は、ソケットをそのマルチキャスト グループとポートにバインドしているこの特定のサーバー上のすべてのプロセスが SO_REUSEADDR オプションを設定するようにすることです。

編集:
上記の最近のコメントに対応するために、これを実際に再現できる 1 つの方法は、データグラム ソケットを同じポートとグループにバインドする 2 つの単純なマルチキャスト リッスン プログラムを作成することです。1 つのプログラムで SO_REUSEADDR オプションを設定し、もう 1 つのプログラムでは設定しないようにします。SO_REUSEADDR が設定されていないプログラムを実行すると、マルチキャスト データが送信されることがわかります。このプログラムを起動したまま、SO_REUSEADDR が設定されている 2 番目のプログラムを実行すると、最初のプログラムがまだマルチキャスト データを受信して​​いる間、マルチキャスト データを受信しないことがわかります (これは、最初に説明した問題を再現するはずです)。

最後に、両方のプログラムをシャットダウンし、最初のプログラムを変更して SO_REUSEADDR を設定し、上記の手順を繰り返します。両方のプログラムがマルチキャスト トラフィックを受信して​​いることがわかります。

于 2016-11-23T15:49:32.887 に答える
0

1つのプロセスから同じ上に複数の開いているソケットを持つことは可能です。同じhost:portプロセスをリッスンする(つまりバインドする)プロセス以上のものを持つことは不可能host:portです。

おそらく、サーバープロセスの以前のインスタンスが強制終了されていません。

Wugが言及している別のオプションは、ルートではないときに1024未満のポートにバインドしようとすることです。ローポート1〜1024の範囲は、有効なUID == 0のアプリケーション用に予約されています(たとえば、rootによって開始されます)。そのような場合ではなく、別のエラーが発生するため、間違った仮定のようですalready in use

于 2012-10-04T19:22:27.980 に答える