#norelated
 #navi(Linux socket プログラミング)
 *目次 [#r1acbd7a]
 #contents
 
 *概要 [#v585200f]
 初っ端から Socket 通信ではないですが、ポート番号から サービス名を検索するプログラムです。 次のポート検索プログラムを作るためにテストとして作ったものでした。ローカルの /etc/services ファイルに記述されていない ポート番号は当然変換できません。 それどころかエラーになってしまいます。
 
 *プログラムのイメージ [#t576958c]
 このプログラムで使われる関数のイメージを以下に示します。あんまり意味ないですね。
 
 |>|>|CENTER:|>|>|c
 |プログラム引数	|入力	|関数	|参照	|ローカルファイル|h
 |ポート番号	|---->	|getservbyport()	|---->	|/etc/services|
 
 *プログラム [#pfca8502]
 CENTER:[[getserv.c>source:getserv.c]]
 CENTER:[[getserv.c>http://github.com/kaizawa/linux-socket/raw/master/getserv.c]]
 
      1  /*
      2   * Probe service name by port number
      3   * cc getserv.c -lnsl -o getserv
      4   */
      5  #include <stdio.h>
      6  #include <errno.h>
      7  #include <netdb.h>
      8  #include <stdlib.h>
      9
     10  int
     11  main(int argc, char *argv[])
     12  {
     13      struct servent *serv ;
     14      int portnum;
     15
     16      if(argc != 2){
     17          printf("Usage: %s port\n", argv[0]);
     18          exit(1);
     19      }
     20
     21      portnum = atoi(argv[1]);
     22      if ( ( serv = getservbyport(htons(portnum),"tcp")) == NULL ){
     23          perror("getservbyport:");
     24          exit(1);
     25      }
     26      printf( "port %d is %s\n", portnum , serv->s_name );
     27      exit(0);
     28  }
 
 ソースファイル [[getserv.c>source:getserv.c]]
 ソースファイル [[getserv.c>http://github.com/kaizawa/linux-socket/raw/master/getserv.c]]
 
 *実行例 [#t218b8f6]
 プログラム名の後に引数としてポート番号を入力します。ここではポート 25 番を指定。
 
  % ./getserv 25
  port 25 is smtp
 
 PORT 25 が SMTP である事が分かります。
 
 *解説 [#v7850ba0]
 |>|getservbyport()|h
 |概要|ポート番号からサービス名を得る|
 |インクルードファイル	|#include <netdb.h>|
 |形式	|struct servent *getservbyport(int port, const char *proto);|
 |引数 	|int  port 	 ポート番号&br;const char *proto 	 プロトコル名|
 |戻り値 |	成功時:		 servent 構造体に求めるサービス名をセットし、 その構造体のポインタを返す。&br;エラー:		 NULL ポインター|
 
 プログラム上では以下のように記述しています。
 
     21      portnum = atoi(argv[1]);
     22      if ( ( serv = getservbyport(htons(portnum),"tcp")) == NULL ){
     23          perror("getservbyport:");
     24          exit(1);
     25      }
 
 21 行目ではプログラムの引数である argv[1] を char 型から int 型に変換してます。&br;
 22 行目で getservbyport() の成功時の戻り値は servent 構造体 へのポインタを返します。ここでもし serv が NULL だった場合には エラーが表示されるようになっています。以下に servent 構造体を示します。servent 構造体は の中で定義されています。
 
  struct servent
  {
    char *s_name;        /* サービス名  */
    char **s_aliases;    /* Alias(別名)リスト */
    int s_port;          /* ポート番号  */
    char *s_proto;       /* 利用するプロトコル  */
  };
 
 getservbyport() の 引数として htons(portnum) と指定していますが、これは 整数(short)「portnum」をホスト形式からネットワーク 形式のバイト順序への変換を行うためです。ということで以上です。
 
     26      printf( "port %d is %s\n", portnum , serv->s_name );
     27      exit(0);
 
 最後は servent 構造体である serv の メンバー s_name (サービス名)をプリントしているだけです。知っている人にとってはだからどうした?と言われそうな事ばかりですが、私にはここまでくるだけでも大変でした。(笑)


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS