以下のポートにソケットをバインドしようとしています:
if( bind(socket_desc,(struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
puts("bind done");
しかし、それは与えます:
$ ./serve
Socket created
bind failed. Error: Address already in use
なぜこのエラーが発生するのですか?
通常、このエラーは、開こうとしているポートがすでに別のアプリケーションによって使用されていることを意味します。 netstatを使用して、開いているポートを確認し、使用可能なポートを使用してみてください。
また、正しいIPアドレスにバインドしているかどうかを確認してください(ローカルホストになると仮定しています)
誰もが正しい。ただし、コードのテストでも忙しい場合、ownアプリケーションは、比較的迅速に開始および停止すると、ソケットを「所有」する可能性があります。ソケットオプションとして SO_REUSEADDR を試してください。
SO_REUSEADDRは正確に何をしますか?
このソケットオプションは、このポートがビジー(TIME_WAIT状態)であっても、先に進んで再利用するようカーネルに指示します。それがビジーであるが、別の状態では、まだ使用中のエラーのアドレスが表示されます。サーバーがシャットダウンされ、ポートでソケットがまだアクティブな間にすぐに再起動された場合に便利です。予期しないデータが入った場合、サーバーが混乱する可能性があることに注意する必要がありますが、これは可能ですが、可能性は低いです。
「ソケットは5タプル(プロト、ローカルアドレス、ローカルポート、リモートアドレス、リモートポート)です。SO_REUSEADDRは、ローカルアドレスを再利用できると言っています。5タプルはまだ一意でなければなりません!」マイケル・ハンター([email protected])。これは事実であり、これが予期しないデータがサーバーに表示される可能性が非常に低い理由です。危険なのは、そのような5タプルがまだネット上で浮いていることです。バウンドしている間に、同じシステム上の同じクライアントからの新しい接続が偶然同じリモートポートを取得します。これについては、「2.7 TIME_WAIT状態を説明してください」でRichard Stevensが説明しています。
そのポートをすでに使用しているプロセスがあります。 netstat -tulpn
を使用すると、特定のポートを使用しているプロセスIDを見つけることができます。
Address already in use
は、現在の実行に割り当てようとしているport
がすでに他のプロセスに割り当てられている/割り当てられていることを意味します。
あなたが開発者であり、多くのテストを必要とするアプリケーションで作業している場合、同じアプリケーションのインスタンスがバックグラウンドで実行されている可能性があります(適切に停止するのを忘れた可能性があります)
このエラーが発生した場合、ポートを使用しているアプリケーション/プロセスを確認してください。
Linuxでは、netstat -tulpn
を使用してみてください。このコマンドは、実行中のすべてのプロセスを含むプロセスリストを一覧表示します。
アプリケーションがポートを使用しているかどうかを確認します。そのアプリケーションまたはプロセスが別の重要なものである場合どのプロセス/アプリケーションでも使用されていない別のポートを使用したい場合があります。
とにかく、ポートを使用するプロセスを停止し、アプリケーションにそれを許可させることができます
Linux環境を使用している場合は、
netstat -tulpn
を使用してプロセスを表示しますkill <pid>
これはプロセスを終了しますWindowsを使用している場合、
netstat -a -o -n
を使用して、ポートの使用状況を確認しますtaskkill /F /PID <pid>
を使用して、そのプロセスを強制終了します上記のように、ポートはすでに使用されています。これにはいくつかの理由が考えられます
close_wait
状態になります。参照( https://unix.stackexchange.com/questions/10106/orphaned-connections-in- close-wait-state )。time_wait
状態にある可能性があります。別の投稿で言及されているように、待機するか、ソケットオプションSO_REUSEADDR
を使用できます。ポートの状態を確認するには、netstat -a | grep <portno>
を実行します。
私もその問題に直面していましたが、解決しました。 クライアント側とサーバー側の両方のプログラムがIDEで異なるプロジェクトにあることを確認してください私の場合NetBeans。次に、localhostを使用していると仮定して、両方のプログラムを2つの異なるプロジェクトとして実装することをお勧めします。