前章ではPOP3サーバに接続したら、すぐに接続を切ってしまいました。
今回は、ユーザー名やパスワードを入力して、サーバーにメールが来ているかどうかをチェックしてみます。
サーバーに接続後
USER USER名\r\nを送信します。成功すると
+OK xxxxxxと返事が来ます。 次に、
PASS パスワード\r\nを送信します。 成功すれば
+OK xxxxxxxと返事が来ます。
これで、ログインできました。 次にLISTコマンドを送ります。 サーバーにメールが来ていれば、
+OK n visible message(xxxx octets) 1 xxxxx 2 xxxxx 3 xxxxx .というような返事が来ます。 最後は「.\r\n」です。 これを受信するまでrecv関数を繰り返して呼び出さなくてはいけません。
では、プログラムを見てみましょう。(もちろん、プロジェクトにWsock32.libを参加させなくてはいけまくせん。)
// pop02.cpp
#include <stdio.h>
#include <winsock2.h>
int main()
{
char szServer[64], szBuf[1024], szPort[8], szUser[64], szPass[64];
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);
printf("ユーザー名---");
gets(szUser);
printf("パスワード---");
gets(szPass);
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");
closesocket(s);
WSACleanup();
return -5;
}
wsprintf(szBuf, "USER %s\r\n", szUser);
send(s, szBuf, (int)strlen(szBuf), 0);
memset(szBuf, '\0', sizeof(szBuf));
recv(s, szBuf, (int)sizeof(szBuf) - 1, 0);
printf(szBuf);
if (strstr(szBuf, "+OK") != szBuf) {
perror("ユーザー名が正しくありません\n");
closesocket(s);
WSACleanup();
return -6;
}
wsprintf(szBuf, "PASS %s\r\n", szPass);
send(s, szBuf, (int)strlen(szBuf), 0);
memset(szBuf, '\0', sizeof(szBuf));
recv(s, szBuf, (int)sizeof(szBuf) - 1, 0);
printf(szBuf);
if (strstr(szBuf, "+OK") != szBuf) {
perror("パスワードが不正です\n");
closesocket(s);
WSACleanup();
return -7;
}
wsprintf(szBuf, "%s\r\n", "LIST");
send(s, szBuf, (int)strlen(szBuf), 0);
while (1) {
memset(szBuf, '\0', sizeof(szBuf));
nRtn = recv(s, szBuf, (int)sizeof(szBuf) - 1, 0);
printf(szBuf);
if (nRtn == SOCKET_ERROR) {
perror("エラーが発生しました\n");
break;
}
if (strstr(szBuf, ".\r\n") != NULL)
break;
}
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;
}
では、実行結果を見てみましょう。
左の例では、プロクシメールを利用しているため、ポート番号は110番以外を使用しています。
直接メールサーバに接続するには110番を使います。
Update Mar/22/2004 By Y.Kumei