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;
      }