29

マスターサーバーと分散スレーブサーバーで構成されるプログラムがあります。スレーブサーバーはステータスの更新をサーバーに送信し、サーバーが特定のスレーブから一定期間連絡がない場合は、スレーブにダウンのマークを付けます。これは一貫して起こっています。

ログを調べたところ、スレーブは1つのステータス更新のみをサーバーに送信でき、その後、別の更新を送信できず、常にconnect()の呼び出しに失敗することがわかりました。「要求されたアドレスを割り当てることはできません(99)。

奇妙なことに、スレーブは他のいくつかの更新をサーバーに送信でき、すべての接続は同じポートで発生しています。この障害の最も一般的な原因は、接続が開いたままになっていることであると思われますが、開いたままになっているものを見つけるのに問題があります。他に考えられる説明はありますか?

明確にするために、これが私が接続している方法です:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

このコードは別のサーバーへの接続を取得する関数内にあり、これら4つの呼び出しのいずれかで失敗すると、関数は失敗します。

4

5 に答える 5

15

問題は、実際にはアドレスがビジーであったことであることが判明しました。ビジー状態は、ネットワーク通信の処理方法における他の問題が原因でした。あなたの入力は私がこれを理解するのを助けました。ありがとうございました。

編集:具体的には、ネットワーク通信を処理する際の問題は、最初に失敗した場合にこれらのステータス更新が常に再送信されることでした。すべての分散スレーブが同時にステータス更新を送信しようとするのは時間の問題であり、ネットワークが過飽和状態になりました。

于 2011-10-04T21:56:38.260 に答える
11

たぶんSO_REUSEADDRはここで役立ちますか? http://www.unixguide.net/network/socketfaq/4.5.shtml

于 2011-10-03T21:08:45.443 に答える
6

これは暗闇の中でのショットです。最初にバインドなしでconnectを呼び出すと、システムがローカルポートを割り当てます。複数のスレッドが接続および切断されている場合は、すでに使用されているポートを割り当てようとする可能性があります。カーネルソースファイルinet_connection_sock.cは、この状態を示唆しています。実験と同じように、最初にローカルポートにバインドしてみてください。各バインド/接続で、異なるローカルポート番号が使用されていることを確認してください。

于 2011-10-03T22:56:00.510 に答える
3

さて、私の問題はポートではなく、バインディングアドレスでした。私のサーバーには、内部アドレス(10.0.0.4)と外部アドレス(52.175.223.XX)があります。私が接続しようとしたとき:

$sock = @stream_socket_server('tcp://52.175.223.XX:123', $errNo, $errStr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);

ローカルソケットが10.0.0.4であり、外部52.175.223.XXではなかったため、失敗しました。を使用して、ローカルで使用可能なインターフェイスをチェックアウトできますsudo ifconfig

于 2020-12-15T10:11:12.600 に答える
-12
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
于 2012-11-12T01:20:55.293 に答える