C/C++socketプログラミングチュートリアルの3:Windowsの下のsocketプログラム


このセクションでは、Windowsの下でSocketについて説明します.Linux Socketを学ぶ読者はスキップできます.
サーバ側コードserver.cpp:
[cpp]  view plain
 copy
#include   
#include   
#pragma comment(lib,“ws 2_32.lib”)/ws 2_のロード32.dll  
  
int main(){  
//DLL 初期化
    WSADATA wsaData;  
    WSAStartup( MAKEWORD(2, 2), &wsaData);  
  
//ソケットの作成
    SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  
  
//バインドソケット    sockaddr_in sockAddr;  
    memset(&sockAddr, 0, sizeof(sockAddr));//バイトごとにを0で埋めます
    sockAddr.sin_family = PF_INET;//IPv 4アドレスを使用
    sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");//具体的なIPアドレス    sockAddr.sin_port = htons(1234);//ポート    bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));  
  
//傍受状態に入る    listen(servSock, 20);  
  
//クライアント要求受信    SOCKADDR clntAddr;  
    int nSize = sizeof(SOCKADDR);  
    SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);  
  
//クライアントへのデータ送信    char *str = "Hello World!";  
    send(clntSock, str, strlen(str)+sizeof(char), NULL);  
  
//ソケットを閉じる
    closesocket(clntSock);  
    closesocket(servSock);  
  
//DLL使用終了    WSACleanup();  
  
    return 0;  
}  
クライアントコードclient.cpp:
[cpp]  view plain
 copy
#include   
#include   
#include   
#pragma comment(lib,“ws 2_32.lib”)/ws 2_のロード32.dll  
  
int main(){  
//DLL 初期化
    WSADATA wsaData;  
    WSAStartup(MAKEWORD(2, 2), &wsaData);  
  
//ソケットの作成
    SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  
  
//サーバへの要求    sockaddr_in sockAddr;  
    memset(&sockAddr, 0, sizeof(sockAddr));//バイトごとにを0で埋めます
    sockAddr.sin_family = PF_INET;  
    sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  
    sockAddr.sin_port = htons(1234);  
    connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));  
  
//サーバからの受信データ    char szBuffer[MAXBYTE] = {0};  
    recv(sock, szBuffer, MAXBYTE, NULL);  
  
//受信データ出力    printf("Message form server: %s", szBuffer);  
  
//ソケットを閉じる
    closesocket(sock);  
  
//DLL の使用終了
    WSACleanup();  
  
    system("pause");  
    return 0;  
}  
server.cppとclient.cppはそれぞれserverにコンパイルする.exeとclient.Exce、serverを先に実行します.Exce、クライアントを再実行します.exe、出力結果:
Message form server: Hello World!
Windowsの下のsocketプログラムはLinuxと同じ考えですが、詳細は異なります.
1)WindowsでのsocketプログラムはWinsockに依存する.dllまたはws 2_32.dll、事前にロードする必要があります.DLLには2つのロード方法があります.ダイナミックリンクライブラリDLLのロードを参照してください.
2)Linuxは「ファイル記述子」の概念を使用し、Windowsは「ファイルハンドル」の概念を使用する.Linuxはsocketファイルと普通のファイルを区別しないで、Windowsは区別します;Linuxではsocket()関数の戻り値はintタイプ、WindowsではSOCKETタイプ、つまりハンドルです.
3)Linuxではread()/write()関数が読み書きされ、Windowsではrecv()/send()関数が送受信されます.
4)SOcketを閉じるとLinuxはclose()関数を使用し、Windowsはclosesocket()関数を使用します.
WinSock(Windows Socket)プログラミングは、システムが提供するダイナミックリンクライブラリ(DLL)に依存し、2つのバージョンがあります.
  • より早いDLLはwsock 32である.dll、サイズ28 KB、対応するヘッダファイルはwinsock 1.h;
  • 最新のDLLはws 2_32.dll、サイズは69 KB、対応するヘッダファイルはwinsock 2.h.

  • ほとんどのWindowsオペレーティングシステムでws 2_がサポートされています.32.dll(パーソナルオペレーティングシステムWindows 95 OSR 2、Windows 98、Windows Me、Windows 2000、XP、Vista、Win 7、Win 8、Win 10およびサーバオペレーティングシステムWindows NT 4.0 SP 4、Windows Server 2003、Windows Server 2008などを含むので、迷わず最新のws 2_を使用できます32.dll.
    DLLを使用する前に、DLLを現在のプログラムにロードする必要があります.コンパイル時にロードするか、プログラムの実行時にロードすることができます.
    」では、この2つのロード方法について説明しています.ダイナミックリンクライブラリDLLのロード:暗黙的ロード(ロード時ロード)と明示的ロード(ランタイムロード)をクリックしてください.
    .
    ここで使用#pragma
    コマンド、コンパイル時にロード:
    #pragma comment (lib, "ws2_32.lib")

    WSAstartup()関数
    DLLを使用する前に、WSAstartup()関数を呼び出して初期化し、WinSock仕様のバージョンを示す必要があります.そのプロトタイプは次のとおりです.
    int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

    wVersionRequestedはWinSock仕様のバージョン番号、低バイトはメインバージョン番号、高バイトはサブバージョン番号(修正バージョン番号)である.lpWsadataはWsadata構造体へのポインタである.
    WinSock仕様について
    WinSock仕様の最新バージョン番号は2.2で、以前は2.1、2.0、1.1、1.0、ws 2_32.dllはすべての仕様をサポートし、wsock 32.dllは1.0および1.1のみをサポートします.
    wsock32.dllはすでにTCP/IP通信プログラムの開発をよくサポートすることができて、ws 2_32.dllは主に他のプロトコルのサポートを追加していますが、最新の
    2.2
    バージョン.
    wVersionRequestedパラメータは、私たちが使用したいバージョン番号を示すために使用されます.そのタイプはWORDで、unsigned shortに等価で、整数なので、MAKEWORD()マクロ関数でバージョン番号を変換する必要があります.例:
    MAKEWORD(1, 2);  //     1,     2,   0x0201
    MAKEWORD(2, 2);  //     2,     2,   0x0202

    WSAdata構造体について
    WSAstartup()関数の実行に成功すると、ws 2_32.dllに関する情報はWsadata構造体変数に書き込まれる.WSAdataの定義は次のとおりです.
    1. typedef struct WSAData {
    2. WORD wVersion; //ws2_32.dll WORD wHighVersion; //ws2_32.dll // null , ws2_32.dll char szDescription[WSADESCRIPTION_LEN+1]; // null , ws2_32.dll char szSystemStatus[WSASYS_STATUS_LEN+1]; unsigned short iMaxSockets; //2.0 unsigned short iMaxUdpDg; //2.0 char FAR *lpVendorInfo; //2.0 } WSADATA, *LPWSADATA; 3 ,szDescription  szSystemStatus , 。 :
       
           
      1. #include
      2. #include
      3. #pragma comment (lib, "ws2_32.lib")
      4. int main(){
      5. WSADATA wsaData;
      6. WSAStartup( MAKEWORD(2, 2), &wsaData);
      7. printf("wVersion: %d.%d
        ", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
      8. printf("wHighVersion: %d.%d
        ", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
      9. printf("szDescription: %s
        ", wsaData.szDescription);
      10. printf("szSystemStatus: %s
        ", wsaData.szSystemStatus);
      11. return 0;
      12. }

      :
      wVersion: 2.2
      wHighVersion: 2.2
      szDescription: WinSock 2.0
      szSystemStatus: Running
      ws2_32.dllでサポートされている バージョンは2.2で、 バージョンも2.2です.
      、WinSockプログラミングの はws 2_をロードすることです.32.dll、WSAstartup() を び して し、 するバージョン を します.
      :http://blog.csdn.net/ctrl_qun/article/details/52454232