zillionプロジェクト開発ブログ サーバプログラム(IPv4)のメモ1 忍者ブログ

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

kurageru.png







ネットワークプログラミングを勉強し始めたので自分用メモ.

 
 

接続を受け付けるソケットの作成

  1. アドレス情報の設定
  2. ソケットの作成
  3. ソケットオプションの設定
  4. bind
  5. listen
使用する構造体
sockaddr_in
servent

使用する関数
htonl
htons
getservbyname
socket
setsockopt
bind
listen


エラー処理は省略.




1,アドレス,ポート番号の設定
アドレス情報はsockaddr_in構造体に格納する .
構造体に格納する値は全てネットワークバイトオーダ

/* /usr/include/netinet/in.h */
struct sockaddr_in
{
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port; /* Port number.  */
    struct in_addr sin_addr; /* Internet address. */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
           __SOCKADDR_COMMON_SIZE -
           sizeof (in_port_t) -
           sizeof (struct in_addr)];
  }; 
sin_family: アドレスファミリ.IPv4の場合はAF_INET.
sin_port:     ポート番号.
sin_addr:    アドレスを格納する構造体.
sin_zero:     パッド.関数の引数では(struct sockaddr *)とキャストして渡すため,
                      サイズの調整.
__SOCKADDR_COMMON (sin_)はマクロでsin_familyと展開される.

 
 
/* /usr/include/netinet/in.h */
typedef uint32_t in_addr_t;
struct in_addr
{
    in_addr_t s_addr;
};	
in_addr_t: 32ビットの型.
s_addr:      アドレス.



/* /usr/include/netdb.h */
struct servent
{
    char *s_name; /* Official service name.  */
    char **s_aliases; /* Alias list.  */
    int s_port; /* Port number.  */
    char *s_proto; /* Protocol to use.  */
};
s_name:    サービス名.
s_aliases: 別名リスト.
s_port:        ポート番号.
s_proto:      利用できるプロトコル名("TCP", "UDP"). 






・sockaddr_inをmemsetで初期化.
・アドレスファミリとアドレスを設定
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
INADDR_ANYはホストのもつ全てのIPアドレス.
htonl関数はホストのバイトオーダをネットワークのバイトオーダ(long型で)に変換する関数.
htonl: host to network long



・ポート番号を設定
 ポート番号は文字列で与えられる.
       ・数字だった場合       
addr.sin_port = htons(atoi(portnum));
           htons: host to network short
 
       ・サービス名だった場合("http"とか)
struct servent *se = 
           getservbyname(portnum, "tcp");
addr.sin_port = se->port;
getservbyname関数はサービス名からポート番号を調べ,servent構造体を返す関数.
サービス名とポート番号の対応は/etc/services
    



2,ソケットの作成

socket(int domain, int type, int protocol);
第一引数: アドレスファミリ
第二引数: プロトコルのタイプ(TCP->SOCK_STREAM, UDP->SOCK_DGRAM)
第三引数: プロトコル.プロトコルファミリが1つのプロトコルのみを
                  サポートする場合は0を指定できる.
返り値:      ディスクリプタ
int soc = socket(addr.sin_family, SOCK_STREAM, 0);



3,ソケットオプションの指定
 
int setsockopt(int socfd, int level, int optname, const void *optval, socklen_t optlen);
第一引数: ソケットのディスクリプタ.
第二引数: オプションの層.ソケット層でオプションを指定するときはSOL_SOCKET.
第三引数: 設定するオプションの名前.
第四引数: オプションに設定する値.
第五引数: 設定する値のサイズ.     




・再利用フラグをONにする
int opt = 1;
setsockopt(soc, SOL_SOCKET,
           SO_REUSEADDR, &opt, sizeof(opt));

再利用フラグがOFFでbindした場合,通信が中断したりすると同じアドレスとポートで再びbindができなくなる.       



4,バインド

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
第一引数: ソケットのディスクリプタ.
第二引数: アドレス構造体.
第三引数: アドレス構造体のサイズ.



・ソケットとアドレスをバインドする.
第二引数は(struct sockaddr *)にキャストする.

bind(soc,
     struct sockaddr *) &addr, sizeof(addr));
//


5,listen
 
int listen(int sockfd, int backlog);
第一引数: ソケットのディスクリプタ.
第二引数: 保留中の接続のキューの最大長.



・接続待ちソケットにする.
listen(soc, SOMAXCONN);
 

拍手[0回]

PR

◎ Post your Comment
Name
Title
E-mail
URL
Comment
Pass   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
◎ この記事へのトラックバック
Trackback URL
◎ カウンター
◎ カレンダー
04 2017/05 06
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
◎ 最新CM
[10/24 名無しの権兵衛]
[08/30 名無しの権兵衛]
[08/14 no name no future]
[08/05 ゲームサークルEaSt]
[07/28 リオウ]
◎ プロフィール
HN:
kyasbal
年齢:
22
性別:
男性
誕生日:
1994/09/22
職業:
人間
趣味:
趣味ねぇ~~う~ん・・・
◎ ブログ内検索
◎ バーコード
◎ アクセス解析
◎ フリーエリア
◎ フリーエリア
Script: Ninja Blog 
Design by: タイムカプセル
忍者ブログ 
[PR]