サーバーに接続後
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