C++ SSL_读取在第一次读取时返回-1
问题:当我第一次调用C++ SSL_读取在第一次读取时返回-1,c++,ssl,openssl,client,C++,Ssl,Openssl,Client,问题:当我第一次调用bytes=SSL_read(SSL,buf,sizeof(buf))它总是返回-1,但是下一个调用返回header,等等。 你能帮我找出我的错误在哪里吗? 我创建SSL对象 呼叫请求 请求示例: POST /some/page HTTP/1.1 Connection: keep-alive Content-Type: text/html;charset=UTF-8 Host: example.com Content-Length: 123 (just for ex.) &
bytes=SSL_read(SSL,buf,sizeof(buf))代码>它总是返回-1,但是下一个调用返回header,等等。
你能帮我找出我的错误在哪里吗?
我创建SSL对象
呼叫请求
请求示例:
POST /some/page HTTP/1.1
Connection: keep-alive
Content-Type: text/html;charset=UTF-8
Host: example.com
Content-Length: 123 (just for ex.)
<mytag /> <mysecondtag />
POST/some/page HTTP/1.1
连接:保持活力
内容类型:text/html;字符集=UTF-8
主持人:example.com
内容长度:123(仅适用于ex.)
创建SSL对象
SSLConnection::SSLConnection(string _server, int _port)
{
int err = 0;
struct sockaddr_in address;
X509* scert;
char* txt;
char buff[4096];
SSL_METHOD *meth;
WORD wVersionRequested;
WSADATA wsaData;
SSLeay_add_ssl_algorithms();
meth = SSLv23_method();
SSL_load_error_strings();
ctx = SSL_CTX_new(meth);
printf("ctx created\n");
if (ctx == NULL) {
bad_ = true;
error_message_ = L"Context is NULL";
return;
}
if (err == -1) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
// Socket initialization and connection to the server.
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
error_message_ = wprintf_s(L"///eRROR EN WSASstartup//%d\n", err);
bad_ = true;
return;
}
sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd == -1) {
bad_ = true;
error_message_ = L"Socket not initialized";
return;
}
memset(&address, '\0', sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(_server.c_str());
address.sin_port = htons(_port);
address.sin_addr.S_un.S_addr = inet_addr(_server.c_str());
err = connect(sd, (struct sockaddr*) &address, sizeof(address));
if (err == -1) {
bad_ = true;
error_message_ = L"Connection not created";
return;
}
// We started the SSL negotiation
ssl = SSL_new(ctx);
if (ssl == NULL) {
bad_ = true;
error_message_ = L"SSL not created";
return;
}
SSL_set_fd(ssl, sd);
// Setting client certificate and key
int res = 0;
res = SSL_use_certificate_file(ssl, "path1", SSL_FILETYPE_PEM);
printf("Cert assigned: %d\n", res);
if (res <= 0) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
res = SSL_use_PrivateKey_file(ssl, "path2", SSL_FILETYPE_PEM);
printf("Key assigned: %d\n", res);
if (res <= 0) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
}
err = SSL_connect(ssl);
if (err == -1) {
ERR_print_errors_fp(stdout);
bad_ = true;
return;
} else printf("SSL Connection established\n");
if (!SSL_CTX_check_private_key(ctx)) {
printf("private key is not valid\r");
}
/* The next two steps are optional */
/* We get the cipher - optional */
// TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
printf("SSL connection using %s\n", SSL_get_cipher(ssl));
cipher = SSL_get_cipher(ssl);
/* We get the Server certificate - optional */
scert = SSL_get_peer_certificate(ssl);
CHK_NULL(scert);
txt = X509_NAME_oneline(X509_get_subject_name(scert), 0, 0);
CHK_NULL(txt);
cert_subject = txt;
OPENSSL_free(txt);
txt = X509_NAME_oneline(X509_get_issuer_name(scert), 0, 0);
CHK_NULL(txt);
cert_issuer = txt;
OPENSSL_free(txt);
X509_free(scert);
}
SSLConnection::SSLConnection(字符串\u服务器,int\u端口)
{
int err=0;
地址中的结构sockaddr_;
X509*scert;
char*txt;
字符buff[4096];
SSL_方法*meth;
单词wVersionRequested;
WSADATA WSADATA;
SSLeay_add_ssl_算法();
meth=SSLv23_方法();
SSL_加载_错误_字符串();
ctx=SSL\u ctx\u新(meth);
printf(“创建的ctx”);
如果(ctx==NULL){
坏=真;
错误消息=上下文为空;
返回;
}
如果(错误==-1){
错误打印错误fp(标准输出);
坏=真;
返回;
}
//套接字初始化和与服务器的连接。
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested和wsaData);
如果(错误!=0)
{
错误消息=wprintf\u s(L////WSASstartup//%d\n“错误”);
坏=真;
返回;
}
sd=套接字(AF_INET,SOCK_STREAM,0);
如果(sd==-1){
坏=真;
错误消息=套接字未初始化;
返回;
}
memset(&address,'\0',sizeof(address));
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(_server.c_str());
address.sin_port=htons(_port);
address.sin_addr.S_un.S_addr=inet_addr(_server.c_str());
err=connect(sd,(struct sockaddr*)和address,sizeof(address));
如果(错误==-1){
坏=真;
错误消息=未创建连接;
返回;
}
//我们开始了SSL谈判
ssl=ssl_新(ctx);
如果(ssl==NULL){
坏=真;
错误消息=未创建SSL;
返回;
}
SSL_set_fd(SSL,sd);
//设置客户端证书和密钥
int res=0;
res=SSL\u使用证书\u文件(SSL,“路径1”,SSL\u文件类型\u PEM);
printf(“分配的证书:%d\n”,res);
if(res)您是否尝试过检查实际错误是什么?调用以获取错误代码,以及检查errno
.Tnx以获取您的评论@JoachimPileborg。您能帮我处理此错误代码吗?(:我这样调用:SSL\u get\u error(SSL,bytes)
在SSL\u read
之后您是否使用非阻塞套接字?
int SSLConnection::request(const char *_request,
map<char *, char *> &_response_headers,
string &_response_body) {
if (bad_) {
bad_ = true;
error_message_ = L"There is no connection";
return -2;
}
// Sending request
printf("Sending request\n");
char buf[100000];
int bytes;
string _tmp_response;
SSL_write(ssl, _request, strlen(_request));
// Reading response
printf("Reading response\n");
int response_size = 0;
bool flag = 0;
int error_count = 0;
while (true) {
Sleep(1000);
bytes = SSL_read(ssl, buf, sizeof(buf));
printf("Bytes: %d\n", bytes);
if (bytes < 0) {
error_count++;
if (error_count > 3) {
bad_ = true;
error_message_ = L"SSL_read: something went wrong!";
printf("SSL_read: something went wrong!\n");
return -1;
}
}
if (bytes == 0) break;
printf("--------- Response (%d)---------\n", bytes);
for (int i = 0; i<bytes; ++i) printf("%c", buf[i]);
printf("\n--------- End response ---------\n");
//if (!flag) flag = 1;
//else {
for (int i = 0; i<bytes; ++i)
_tmp_response += buf[i];
response_size += bytes;
//}
buf[0] = 0;
}
_tmp_response.resize(response_size);
closesocket(sd);
SSL_free(ssl);
SSL_CTX_free(ctx);
return 1;
}