C++ソケットプログラミングの基礎知識紹介

4116 ワード

ほんの少し
Linuxネットワークプログラミングには、ユーザ状態ネットワークプログラミングとカーネル状態ネットワークプログラミングが含まれます.
WindowsプラットフォームでもLinuxプラットフォームでも、ソケットに対して独自のプログラミングインターフェースを実現しています.Windowsの下にあるSocketインプリメンテーションをWindows Socketと呼びます.Linuxの下の実現には2つのセットがあります:1セットはバークリーのセットのインターフェースで、Berkeley Unixに起源して、このインターフェースはとても簡単で、広範な応用を得て、すでにLinuxのネットワークのプログラミングの事実上の標準になりました;もう1つは伝送層インタフェースであり、System Vシステム上のネットワークプログラミングAPIであるため、このプログラミングインタフェースはUnix上で使用されることが多い.
Socketはアプリケーション層と伝送層の間の抽象層であり、TCP/IP層の複雑な操作をいくつかの簡単なインタフェース供給用層に抽象化して呼び出し、プロセスのネットワークでの通信を実現する.
Socketプログラミングインターフェースは、ユーザプロセス(アプリケーション層)と伝送層またはネットワーク層との間のプログラミングインターフェースである.
にネットワークプログラムアーキテクチャ
1つはB/Sアーキテクチャです.ブラウザがWebサイトのWebページを表示するのは、このアーキテクチャの下でのアプリケーションです.
1つはC/Sアーキテクチャです.例えば、私たちのコンピュータにインストールされているQQプログラムはクライアントですが、テンセント社内にはサーバー側のプログラムもあります.
ソケットベースのネットワークプログラミングでは、C/Sアーキテクチャが一般的に使用されます.簡単なクライアントとサーバ間の通信手順は、次のとおりです.
1クライアントがサーバに要求します.
2サーバはクライアントから要求を受けて分析処理を行う.
3サーバは、処理の結果をクライアントに返します.
3ソケットタイプ
Linuxには3種類のソケットがあります
  • ストリームソケット:SOCK_STREAM
  • データレポートソケット:SOCK_DGRAM
  • オリジナルソケット:SOCK_RAW

  • 元のソケットと標準ソケット(標準ソケットはストリームソケットとデータレポートソケットを含む)の違い:元のソケットはカーネルが処理していないIPパケットを読み書きすることができ、ストリームソケットはTCPプロトコルのデータしか読めず、データレポートソケットはUDPプロトコルのデータしか読めない.
    よんソケットアドレスこうぞう
    1点目
    AFはADDRESS FAMILYアドレス族、PFはPROTOCOL FAMILYプロトコル族を表すが、この2つのマクロ定義は同じであるため、どちらを使っても構わない.
    Winsock2.h中#define AF_INET 2,#define PF_INET AF_INETだからwindowsでAF_INETとPF_INETは全く同じです.
    Unix/Linuxシステムでは、バージョンによってわずかな違いがあります.
    BSDの場合、AFです.
    POSIXについてはPFである.
    UNIXシステムサポートAF_INET,AF_UNIX,AF_NS等
    DOSでは、WindowsではAF_のみサポートされていますINET、インターネットエリアです.
    異なるプロトコルファミリーのソケットアドレスの意味は異なり、例えばAF_INETのアドレスはstruct sockaddr_in,
    ドメインソケットAF_INETのアドレスはstruct sockaddr_un
    2 sockaddr_in説明
    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)];
      };

    __SOCKADDR_COMMONはマクロであり、/usr/include/bits/sockaddrに定義されている.h
    #define __SOCKADDR_COMMON(sa_prefix) \                  
      sa_family_t sa_prefix##family

    :続行記号
    ##:前後の2つのパラメータを接続する
    __SOCKADDR_COMMON (sin_);

    マクロが展開されると、次のようになります.
    sa_family_t sin_family

    sa_family_tは/usr/include/bits/sockaddrに定義する.h
    typedef unsigned short int sa_family_t;

    だから_SOCKADDR_COMMON (sin_);マクロ展開後の最終結果はunsigned short int sin_family
    5ホストバイト順
    1点目
    小端バイト順:データの低バイトはメモリの低アドレスに保存され、データの高バイトはメモリの高バイトに保存されます.
    大端バイト順:データの低バイトはメモリ高アドレスに保存され、データの高バイトはメモリ低バイトに保存されます.
    2ホストのバイト順をテストする
    2.1コード
    #include 
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        int nNum = 0x12345678;
        char *p = (char*)&nNum;  //p    nNum       
         
        if (*p == 0x12) cout << "This machine is big endian." << endl; //               
        else cout << "This machine is small endian." << endl;   
      
        return 0;
    }

    2.2運転
    [root@localhost test]# g++ -o test test.cpp
    [root@localhost test]# ./test
    This machine is small endian.

    2.3説明
    この機はx 86機で、x 86機は基本的に小端モードです.
    ろくてきネットワークバイトシーケンス
    1点目
    ネットワークバイト順は、TCP/IPに規定されたデータ表示フォーマットであり、具体的なCPUタイプ、オペレーティングシステムとは無関係であり、異なるホスト間でデータを転送する際に正確に解釈できることを保証することができる.ネットワークバイト順は、大端ソート方式を採用しています.
    アプリケーションを開発する際には、ネットワークバイト順の使用を保証する必要があります.そのため、ホストのバイト順からネットワークバイト順に変換してからデータを発行し、受信者がデータを受け取った場合もホストバイト順に変換してから処理する必要があります.
    2ホストバイト順とネットワークバイト順の相互変換の関数.
    uint32_t htonl(uint32_t hostlong);   //32      
    uint16_t htons(uint16_t hostshort);  //16      
    uint32_t ntohl(uint32_t netlong);    //32      
    uint16_t ntohs(uint16_t netshort);   //16