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);
注意事項
以上のやり方では,非同期通信に対応していませんので,非同期接続についてはまた後日記述します.