12

OSはLinuxです。ポートをリアルタイムで変更できるサーバー プロセスがあります。ただし、バインドする前にポートが空いているかどうかを事前に知りたいです。

シナリオ: サーバーは localhost:5000 にバインドし、localhost:6000 にバインドする要求を受け取ります。サーバーは、ポートが空いているかどうかを確認する必要があります。この質問では、ポートが空いているかどうかをチェックするルーチンを提供する回答を探します。

記録のために、ポートが自由に使用できるかどうかを確認するコード スニペットを使用して質問を編集しています。これは、それが使用されるという意味ではありません。以下のコードは、「ポートが現在利用可能な場合」という質問に対する回答であり、使用していません。ソケットを開き、bind が EADDRINUSE を返し、ソケットを閉じるかどうかを確認します。

#include <iostream>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>

int main(int argc, char **argv) {

    struct sockaddr_in serv_addr;
    if( argc < 2 )
        return 0;
    int port = atoi(argv[1]);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if( sockfd < 0 ) {
        printf("socket error\n");
        return 0;
    } else {
        printf("Opened fd %d\n", sockfd);
    }

     bzero((char *) &serv_addr, sizeof(serv_addr));
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(port);
     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {

        if( errno == EADDRINUSE )
        {
            printf("the port is not available. already to other process\n");
        } else {
            printf("could not bind to process (%d) %s\n", errno, strerror(errno));
        }
    }

    if (close (sockfd) < 0 ) {
        printf("did not close fd: %s\n", strerror(errno));
        return errno;
    }

    return 0;


}

ここにいくつかのサンプル実行があります (部分的な出力)

[bash{1051}{51}]:[~/some_sources/checkbind]::./a.out 41067
the port is not available. already to other process
[bash{1052}{52}]:[~/some_sources/checkbind]::./a.out 22
could not bind to process (13) Permission denied
[bash{1053}{53}]:[~/some_sources/checkbind]::./a.out 22000
Opened fd 3
4

3 に答える 3

12

システム上の他のプロセスが並行してポートにバインドしている可能性があるため、これは明らかな競合状態です。したがって、見つけた解決策は不完全であり、「失敗した場合は新しいポート番号を選択して再試行する」アプローチに従ってそれを記述する必要があります。bind()

于 2012-04-24T09:09:50.883 に答える
7

サーバーが使用するポートを指定されている場合は、それで十分bind()です。真剣に。

確かに/proc/net/tcp、ポートが使用されているかどうかを解析して確認できます。しかし、その後は?ポートが空いていることを知っているので、まだ呼び出す必要がありbind()ます。とにかくポートが空いているかどうかを教えてくれるので/proc/net/tcp、(遅い!) 文字列の生成と解析と余分なカーネルトリップは、あまり最適化されていない (読み取り: に比べて非常に遅いbind()) 診断パスを通過し、解析が完了する前に古くなっている可能性がある情報を取得します。だから電話bind()して幸せになってください。

于 2012-04-25T07:25:10.290 に答える