2012-01-04 11 views
4

IPアドレスとポート番号を合わせてプロセスIDを一意に識別できますか?IPアドレスとポート番号を合わせてプロセスIDを一意に識別できますか?

IPアドレスとポート番号を指定して、対応するプロセスIDを取得する方法を探していますが、そのようなIP /ポートのペアが1つのPIDを一意に識別できるかどうかはわかりません。

+3

ポート2100でリッスンして取得します。 – TJD

+0

@TJD "何もしない"というのは、特定のIP /ポートの組み合わせにバインドするプロセスが必要なので、あまり適切ではありません。 – MartinStettner

+0

@MartinStettnerでは、「プロセス」の概念を持つOSなしで、組み込みマイクロコントローラ上でIPアドレスとポートを使用できます。質問とタグは、OSについては何も示していません。 – TJD

答えて

12

必ずしもそうではありません。ソケットがプロセスで開かれた/受け入れられた後にforkすると、子プロセスもソケットをオープンしているので、IPアドレスとポート番号は2つのプロセスによって使用されます。

0

Windowsマシンでは、待機中のアプリケーションのプロセスIDを取得できます。 this questionを参照してください。

1

ジョナサンが指摘したように、関係は必ずしも一意ではありません。たとえば、子プロセスを使用して要求を同時に処理するサーバー実装(Apache/Prefork)があります。

しかし(シングルポート/アドレスペアに対して複数のエントリがあるかもしれないが)とにかく、特定のポート/アドレスを使用してプロセスのリストを取得することができ、おそらくあなたの特定のケースで、これは実行可能なソリューションです:

たとえば、Windowsの場合、GetExtendedTcpTable関数を使用して、パラメータをTCP_TABLE_OWNER_MODULE_*値の1つに設定します。現在のすべてのTCPエンドポイントのローカルおよびリモートアドレス/ポートとプロセスIDを含むテーブルが返されます。

Linuxでは確かに同様の方法がありますが(これはどうやってどうすればいいのか分かりませんが)、これはまさにnetstat -pプログラムが行うことなのでです。

1

一度に1つのプロセスだけが特定のポートにバインドできるため、最大で1つのプロセスがそれをリッスンできるポートが与えられます。 複数のプロセスが同じポートを介して送受信できますが、1つのプロセスだけがポートにバインドします。

次のコードでは、 "server:bind:Address already in use"を取得します。エラー。我々はlsofを-i実行する場合次に、:2100我々はそう何の何の接続または独自のマッピングが存在しない、唯一のプロセスIDは、IPアドレスとポートは、プロセスIDとは何の関係もない

#define SERVERPORT "2100" 
#define BUF_MAX 1024 
#define BACKLOG 10 
int data_connection(char* portno) 
{ 
    struct addrinfo hints,*res,*clientinfo; 
    int rv,datafd,yes=1,new_fd; 
    char buf[BUF_MAX]; 
    struct sockaddr_storage their_addr; 
    socklen_t addr_size; 

    memset(&hints,0,sizeof(hints)); 
    hints.ai_family=AF_UNSPEC; 
    hints.ai_socktype=SOCK_STREAM;//connnection oriented. 
    hints.ai_flags=AI_PASSIVE; 

    if ((rv = getaddrinfo(NULL, portno, &hints, &res)) != 0) { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     return 1; 
    } 
    for(clientinfo=res;clientinfo!=NULL;clientinfo=clientinfo->ai_next) 
    { 
     if((datafd=socket(clientinfo->ai_family,clientinfo->ai_socktype,clientinfo->ai_protocol))==-1) 
     { 
      perror("server:datasocket"); 
      continue; 
     } 
     break; 
    } 

    if(setsockopt(datafd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1) 
    { 
     perror("setsockopt"); 
     exit(1); 
    } 

    if(bind(datafd,clientinfo->ai_addr,clientinfo->ai_addrlen)<0) 
    { 
     perror("server:bind"); 
     exit(1); 
    } 
    if(listen(datafd,BACKLOG)<0) 
    { 
     perror("server:listen"); 
     exit(1); 
    } 
    addr_size=sizeof(their_addr); 
    if((new_fd=accept(datafd,(struct sockaddr*)&their_addr,&addr_size))<0) 
    { 
     perror("server:accept"); 
     exit(1); 
    } 
    close(datafd); 
    datafd=new_fd; 

    return datafd; 
} 
int main() 
{ 
    int datafd; 
    fork(); 
    datafd=data_connection(SERVERPORT); 

} 
関連する問題