今回は、実際にPOP3サーバに接続するプログラムを作ります。
接続したら、サーバーからどのような返事が来るかも観察します。 接続に成功したら"QUIT"コマンドを送信してすぐに接続を切って終了します。
何かばかばかしいようなプログラムですが、この方法がわかるといろいろと応用 が効くようになります。
では、さっそくプログラムを見てみましょう。
// pop01.cpp #include <stdio.h> #include <winsock2.h> int main() { char szServer[64], szBuf[1024], szPort[8]; u_int port; WSADATA wsaData; int nRtn; SOCKET s; SOCKADDR_IN saddr; HOSTENT *lpHost; unsigned int addr; printf("POP3サーバー---"); gets(szServer); printf("ポート番号---"); gets(szPort); if (strcmp(szPort, "") == 0) strcpy(szPort, "110"); port = (u_int)atoi(szPort); printf("ポート番号を%dに設定しました\n", port); nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData); if (nRtn != 0) { perror("WSAStartupp失敗です\n"); return -1; } s = socket(PF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { perror("ソケット作成失敗\n"); WSACleanup(); return -2; } lpHost = gethostbyname(szServer); if (lpHost == NULL) { addr = inet_addr(szServer); lpHost = gethostbyaddr((char *)&addr, 4, AF_INET); wsprintf(szBuf, "%sが見つかりません\n", szServer); perror(szBuf); return -3; } memset(&saddr, 0, sizeof(SOCKADDR_IN)); saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list); if (connect(s, (PSOCKADDR)&saddr, sizeof(saddr)) != 0) { perror("サーバーソケットに接続失敗\n"); closesocket(s); WSACleanup(); return -4; } memset(szBuf, '\0', sizeof(szBuf)); recv(s, szBuf, (int)sizeof(szBuf) - 1, 0); printf(szBuf); if (strstr(szBuf, "+OK") != szBuf) { perror("サーバーは+OKを返しませんでした\n"); } strcpy(szBuf, "QUIT\r\n"); send(s, szBuf, (int)strlen(szBuf), 0); memset(szBuf, '\0', sizeof(szBuf)); recv(s, szBuf, (int)sizeof(szBuf) - 1, 0); printf(szBuf); closesocket(s); WSACleanup(); return 0; }WSAStartup関数でWinsockの初期化をして、socket関数でソケットを作成します。 ここまでは、たいていのプログラムで同じ手順を踏みます。
gethostbyname関数でホスト情報を取得します。ユーザーがサーバー名でなく IPアドレスで指定した場合は失敗します。 失敗したら、inet_addr関数で変換してからgethostbyaddrを呼び出します。
SOCKADDR_IN構造体に必要事項をセットして、connect関数で、接続を確立します。 あとは、send, recv関数でやりとりをするだけです。
POP3サーバーにコマンドを送るときは末尾に「\r\n」を付加します。 コマンドが成功したら「+OK ****」の返事が来ます。
では、さっそく実行してみましょう。 この例では、LAN内に設置してあるPOP3サーバを利用しています。 インターネット上のサーバーでも同じです。
ポート番号を聞かれた時に、何も入力せずにエンターキーを押すと自動的に110に設定 されるようになっています。
Update Mar/04/2004 By Y.Kumei