第96章 POP3サーバにログインする


前章では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番を使います。




[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Mar/22/2004 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。