GNU/Linux >> Linux の 問題 >  >> Linux

connect() が EADDRNOTAVAIL を返すのはなぜですか?

このリンクを確認してください

http://www.toptip.ca/2010/02/linux-eaddrnotavail-address-not.html

編集 :はい、もっと追加するつもりでしたが、緊急のためにそこでカットしなければなりませんでした

再接続を試みる前にソケットを閉じましたか?閉じると、ソケットペア (ip/port) が解放されたことがシステムに通知されます。

追加の項目もご覧ください:

  • ローカル ポートが指定されたリモート IP とポートに既に接続されている場合 (つまり、同一のソケット ペアが既に存在する場合)、このエラーが発生します (以下のバグ リンクを参照してください)。
  • ローカルのものではないソケットアドレスをバインドすると、このエラーが発生します。マシンの IP アドレスが 127.0.0.1 と 1.2.3.4 で、1.2.3.5 にバインドしようとすると、このエラーが発生します。
  • EADDRNOTAVAIL:指定されたアドレスがリモート マシンで利用できないか、名前構造体のアドレス フィールドがすべてゼロです。

あなたに似たバグとリンクしてください (答えは一番下にあります)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294599

あなたのソケットは基本的に TCP 内部状態の 1 つでスタックしているようで、再接続の遅延を追加すると、そのバグ レポートで行われたように、問題が解決する可能性があります。


使用可能な一時ポートの数を変更したくない場合 (David の提案による)、または理論上の最大数よりも多くの接続が必要な場合は、使用中のポートの数を減らす方法が他に 2 つあります。ただし、これらはさまざまな程度で TCP 標準に違反しているため、注意して使用する必要があります。

最初は SO_LINGER をオンにすることです TCP を強制的に 0 秒のタイムアウトで stack を使用して RST パケットを送信し、接続状態をフラッシュします。ただし、微妙な点が 1 つあります。shutdown を呼び出す必要があります。 close する前にソケットファイル記述子に 、 FIN を送信するチャンスがあるように RST の前のパケット パケット。したがって、コードは次のようになります:

shutdown(fd, SHUT_RDWR);
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_LINGER,
           (char *) &linger, sizeof(linger));
close(fd);

FIN パケットは RST で並べ替えられます

詳細については、TCP オプション SO_LINGER (ゼロ) - 必要な場合を参照してください。 (実験的には、 setsockopt をどこに設定しても問題ないようです .)

2 つ目は、SO_REUSEADDR を使用することです。 および明示的な bind (あなたがクライアントであっても)、Linux は実行時に一時的なポートを再利用できるようになります。 しなければならないことに注意してください bind を使用 INADDR_ANY で およびポート 0 、それ以外の場合は SO_REUSEADDR 尊重されません。コードは次のようになります:

int opts = 1;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
         (char *) &opts, sizeof(int));

struct sockaddr_in listen_addr;
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = 0;
listen_addr.sin_addr.s_addr = INADDR_ANY;
// todo: test for error
bind(fd, (struct sockaddr *) &listen_addr, sizeof(listen_addr));

// todo: test for addr
// saddr is the struct sockaddr_in you're connecting to
connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));

netstat -an | grep -e tcp -e udp | wc -l のように、TCP 接続の内部カーネル データ構造を飽和させてしまうため、このオプションはあまり適していません。 .ただし、これが発生するまでポートの再利用は開始されません。


これは、0 などの無効なポートが指定された場合にも発生する可能性があります。


Linux
  1. cpを取得する理由:Linuxでのディレクトリエラーの省略と解決方法

  2. Ssh – Sshの接続に時間がかかるのはなぜですか?

  3. glibc の fclose(NULL) がエラーを返す代わりにセグメンテーション違反を引き起こすのはなぜですか?

  1. ENOENT が No such file or directory を意味するのはなぜですか?

  2. Linux サービスを作成しているときに Exec フォーマット エラーが発生するのはなぜですか?

  3. 画像を wget すると、画像ではなくファイルが返されるのはなぜですか?

  1. `md5sum`がインターネットと同じハッシュを与えないのはなぜですか?

  2. カーネルがパケットをドロップするのはなぜですか?

  3. webdav を使用した apache2.4 で 405 エラーが発生する