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);

注意事項

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