次のような手順で接続します。
1.WSAStartup関数でwinsockを初期化します。 2.socketをオープンします。 3.connect関数でサーバに接続します。接続するとサーバーから返事が来ます。これをrecv関数で受け取ります。
今回は接続してサーバーから返事が来たらすぐに接続を終了するプログラムを作ります。 これには、サーバーに「QUIT\r\n」コマンドをsendします。
接続を切ったらsocketをクローズしてWSACleanup関数でクリーンアップします。
では、ここで使う関数を見てみましょう。
SOCKET socket( int af, int type, int protocol );ソケットを生成します。
typeには、ソケットのタイプを指定します。
TCPならSOCK_STREAM、UDPならSOCK_DGRAMを指定します。
ここでは、TCPなのでSOCK_STREAMを指定します。
protocolには、PF_INETの場合0を指定します。
成功すれば、ソケット記述子(ハンドル)が返されます。
失敗した場合は、INVALID_SOCKETが返されます。
int connect( SOCKET s, const struct sockaddr FAR *name, int namelen );指定のソケットに接続を確立します。
成功したら0が返されます。失敗したらSOCKET_ERRORが返されます。
さて、nameはsockaddr構造体へのポインタを指定します。
sockaddr構造体は次のように定義されています。
struct sockaddr { u_short sa_family; char sa_data[14]; };このままでは、自由度が大きすぎて使いにくいのでsockaddr_in構造体に 必要事項をセットしてsockaddr構造体に型キャストして使用します。
struct sockaddr_in{ short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; };sin_familyはアドレスファミリィでAF_INETにします。
sin_portにはポート番号を指定します。
ポート番号はネットワークバイトオーダーに変換する必要があります。
2バイト以上の数値はインターネットでは「ビッグエンディアン」で記録/送信する決まりになっています。
これは、最上位バイトから順に記録/送信することを意味します。
一方インテル社のCPU(Windows)では「リトルエンディアン」が採用されています。
ネットワーク上で採用されているバイトオーダーをネットワークバイトオーダーといいます。
unsigned int値をネットワークバイトオーダーに変換するにはhtons関数を使います。
u_short htons( u_short hostshort );(u_shortはunsigned short)
sin_addrはin_addr構造体です。
struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; };S_un_bは4つのu_charでフォーマットされたホストのアドレスです。
S_un_wは2つのu_shortでフォーマットされたホストアドレスです。
S_addrはu_longでフォーマットされたホストアドレスです。
sin_zeroはsockaddr構造体とサイズを同じにするためのバディングです。
通常sockaddr_in構造体を設定するには
SOCKADDR_IN sockadd; sockadd.sin_family = AF_INET; sockadd.sin_port = htons(110); sockadd.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list);のような感じで行います。
typedef struct sockaddr_in SOCKADDR_IN;
のようにtypedefされています)
lpHostはgethostbynameまたは、gethostbyaddrで取得できますね。
int recv( SOCKET s, char FAR *buf, int len, int flags );接続したソケットからデータを読み込みます。
成功したら読み込んだデータの長さ(バイト)を返します。
失敗したらSOCKET_ERRORを返します。
int send( SOCKET s, const char FAR *buf, int len, int flags );接続したソケットにデータを送ります。
sはソケットです。
bufは送信するデータを格納するバッファです。
lenはbuf中のデータの長さです。
flagsは通常0を指定します。
成功したら送信したバイト数を返します。
失敗したらSOCKET_ERRORが返されます。
さて、これでPOP3サーバに接続する準備ができました。 次章では実際にPOP3サーバに接続してみます。
Update Feb/23/2004 By Y.Kumei