ラボ講座‎ > ‎Visual C++講座‎ > ‎

socket通信

ここでは,Win32APIを利用したソケット通信プログラムの基本について書きます.というか覚書ですので,下記のコードは不完全なものです(適 切に変数宣言する必要があります)

利用するライブラリ

ヘッダファイルとして以下を指定しましょう.

 #include <WinSock.h>

Winsockライブラリにも3種類ほどバージョンがあるようです.(調査中)

WinSockの初期化

ソケットプログラミングをするためには,まずはWinsockを呼び出さなければなりません.


    if((ret=WSAStartup(MAKEWORD(1,1), &wsa))){
      //ここに エラー処理を書く
    }
 

ソケットを開く 

SOCKET sock=INVALID_SOCKET;
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);       //ソケット作成失敗
    if(sock==INVALID_SOCKET){
   //ここにエラー処理を書く 
     }    

 アクセスするホスト情報の指定の仕方

Winsockによる通信では,IPによる接続を行います.接続先のサーバのの指定には一般的には

  • ホスト名による指定
  • IPアドレスによる直接指定

の2つがあります.Winsockプログラミングではどちらにも対応できますが,ホスト情報を管理する構造体に値を設定する必要がありま す.Winsockにおいて利用する構造体は

  • HOSTENT構造体 ・・・ IP情報の管理
  • SOCKADDR_IN構造体 ・・・ソケット接続のための接続先ホストの情報の管理(ポート番号を含む)

 の2つです.

ホスト名による指定

DNSで管理されたホストに接続する場合は,そのホスト名から以下の関数を利用することでIP情報を入手することができます.

HOSTENT *phe;
LPCSTR host;

if(!(phe=gethostbyname(host))){                 
  //エラー処理
 }

 IPアドレスによる指定

DNSで管理されていない場合は,直接IPを指定する必要があります.その際は以下のようにします.

HOSTENT *phe;
LPCSTR ip;
unsigned long addr;

addr = inet_addr(ip);
if(!(phe = gethostbyaddr((const char *)&addr , 4 , AF_INET))){   
  //エラー処理
 }

 

 Winsockを利用するには,HOSTENT構造体に格納されたホスト情報をSOCKADDR_IN構造体へ格納する必要があります.

SOCKADDR_IN saddin;

//構造体初期化
memset(&saddin, 0x00, sizeof(saddin));                  
saddin.sin_family = AF_INET;
// ポート番号格納
saddin.sin_port   = htons(PORT);            
                           
//アクセス先(サーバ)の情報を sadin に格納している
 memcpy(&saddin.sin_addr, phe->h_addr, phe->h_length);   //アドレス値格納

 ソケットを使ってsaddinが指し示すホストへ接続します.

//接続処理
    if(connect(sock, (LPSOCKADDR)&saddin, sizeof(saddin))==SOCKET_ERROR){
        if(WSAGetLastError()!=WSAEWOULDBLOCK){
            closesocket(sock);
            sock=INVALID_SOCKET;
        }
    }

データの送受信

送信にはsend関数,受信にはrecv関数を用います.

send(sock,buf, strlen(buf)+1, 0);
recv(sock, buf2, strlen(buf)+1, 0);

注意事項

以上のやり方では,非同期通信に対応していませんので,非同期接続についてはまた後日記述します.

 

Comments