我正在尝试使用 winsock/OpenSSL 制作简单的 IMAP 客户端,这是否可以在没有额外库的情况下实现?如果是这样,如何发送请求并得到响应?服务器只响应一次,即使没有请求,之后我发送请求和应用程序卡在 SSL_read(..) 函数,而不是超时和 BYE。如何发出正确的请求?
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;
}
最佳答案
我没有深入分析您的代码,但我可以看出一个明显的问题。 根据RFC 3501 :
All interactions transmitted by client and server are in the form of lines, that is, strings that end with a CRLF. The protocol receiver of an IMAP4rev1 client or server is either reading a line, or is reading a sequence of octets with a known count followed by a line.
在您的代码中,您没有使用 CRLF 终止命令。尝试更换
strcpy(requestBuf,"a001 CAPABILITY");
与
strcpy(requestBuf,"a001 CAPABILITY\r\n");
此外,您最好在没有 SSL 的情况下开始,然后再添加它 - 这将大大简化调试(即使用 Wireshark )。
关于c++ - imap 客户端 - 如何编写正确的请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13776459/