1

winsock / OpenSSLを使用して単純なIMAPクライアントを作成しようとしていますが、これは追加のライブラリなしで可能ですか?もしそうなら、どのようにリクエストを送信して応答を得るのですか?サーバーは、リクエストがなくても1回だけ応答します。その後、タイムアウトとBYEよりもSSL_read(..)関数でスタックしたリクエストとアプリケーションを送信しています。適切なリクエストを行うにはどうすればよいですか? ここに画像の説明を入力してください

bool RequestQueue(const char* serverName)
{
    SOCKET      hSocket = INVALID_SOCKET;
    char        receiveBuf[512];
    ZeroMemory(receiveBuf,512); 
    char        requestBuf[512];
    ZeroMemory(requestBuf,512); 
    sockaddr_in sockAddr = {0};
    bool        bSuccess = true;

    //SSL
    SSL* ssl;
    SSL_CTX* ctx;

    try
    {       
        //Look up hostname and fill sockaddr_in structure
        cout<< "Looking up hostname "<<serverName<<"...";
        FillSockAddr(&sockAddr,serverName,IMAP_SERVER_PORT);
        cout<< "found.\n";

        //creating socket
        cout<<"Creating socket..";
        if((hSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)
            throw exception("could not create socket!");
        cout<<"created.\n";

            //Connect to server
        cout<<"Attempting to connect to "<< inet_ntoa(sockAddr.sin_addr)
            <<":"<<IMAP_SERVER_PORT<<" ...";
        if(connect(hSocket,(sockaddr*)(&sockAddr),sizeof(sockAddr))!= 0)
            throw exception("could not connect!");

        cout<<"connected\n";

        ctx = SSL_CTX_new(SSLv23_client_method());
        if(!ctx)
            throw exception("SSL_CTX_new error");

        ssl = SSL_new(ctx);
        SSL_CTX_free(ctx);
        if(!ssl)
            throw exception("ssl initializing error");

        SSL_set_fd(ssl,hSocket);
        if(SSL_connect(ssl) != 1)
            throw exception("SSL_connect error");

        int reqLen;
        int retLen;
        cout<<"==============\n";
        cout<<"====begin=====\n";
        cout<<"==============\n";

        retLen = SSL_read(ssl,receiveBuf,sizeof(receiveBuf));
        if(retLen<0)
            throw exception("SSL_read error.");
        cout<<"S: "<<receiveBuf;

        strcpy(requestBuf,"a001 CAPABILITY");
        reqLen = strlen(requestBuf);
        SSL_write(ssl,requestBuf,reqLen);
        cout<<"C: "<<requestBuf<<endl;  

        ZeroMemory(receiveBuf,sizeof(receiveBuf));
        retLen = SSL_read(ssl,receiveBuf,sizeof(receiveBuf));
        if(retLen<0)
            throw exception("SSL_read error.");

        cout<<"S: "<<receiveBuf;                    
    }
    catch(exception e)
    {
        cout<<"Error : "<<e.what()<<endl;
    }
    if(hSocket != INVALID_SOCKET)
    {
        SSL_shutdown(ssl);
        closesocket(hSocket);
        SSL_free(ssl);      
    }

    return bSuccess;
}
4

1 に答える 1

3

私はあなたのコードを深く分析しませんでしたが、1つの明らかな問題を見ることができます。RFC 3501によると:

クライアントとサーバーによって送信されるすべての対話は、行、つまりCRLFで終わる文字列の形式です。IMAP4rev1クライアントまたはサーバーのプロトコルレシーバーは、行を読み取っているか、既知のカウントの後に行が続くオクテットのシーケンスを読み取っています。

コードでは、コマンドをCRLFで終了していません。交換してみてください

strcpy(requestBuf,"a001 CAPABILITY");

strcpy(requestBuf,"a001 CAPABILITY\r\n");

また、SSLなしで開始し、後で追加することをお勧めします。これにより、デバッグが大幅に簡素化されます(つまり、Wiresharkを使用)。

于 2012-12-08T11:12:45.903 に答える