如果winsock2套接字是非阻塞的,与之关联的SSL对象是否也会表现出非阻塞行为?

时间:2015-04-22 18:16:23

标签: c++ c sockets openssl winsock2

我问这个问题是因为我不确定SSL对象是否将套接字视为消息的接收器/源,就像它对BIO对象一样。我的直觉告诉我是的,但我不确定。

目标: 我正在将SSL身份验证集成到现有的TCP代码中。我不想调用传统的send()/ receive(),而是通过OpenSSL的SSL_read()/ SSL_write()来引导消息。我的另一个要求是通信是非阻塞的,数据可以部分发送。

以下是我将SSL对象与套接字关联的方式(服务器代码)。

SSL_Init(std::wstring &peer_hostname, SOCKET sock){
        //...
        //Initialize SSL structure
                ssl = SSL_new(context);
                if (ssl == NULL){
                    mr = APPZRETURN(E_FAIL, L"%ls (%d) : SSL_new failed. Unable to create SSL structure", __FUNCTIONW__, __LINE__);
                }

                //Agent uses winsock class, but OpenSSL uses unix socket. Surpressed warning added here for 4244. It works
                if (SSL_set_fd(ssl, sock) == 0){    //set file descriptor for ssl
                    //Operation failed
                    return -1;
        }
        //...
        int status = SSL_accept(ssl);   
        SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE);
        //...
    }

根据SSL_read()[https://www.openssl.org/docs/ssl/SSL_read.html]的文档,如果底层BIO是非阻塞的,则SSL是非阻塞的。如果我的假设是正确的,这是否意味着如果套接字是非阻塞的,那么SSL也是如此?

扩展我的问题:默认情况下,winsock tcp套接字是非阻塞的(假设我已经创建了一个TCP套接字,但没有调用ioctlsocket并设置非阻塞模式)

感谢您抽出宝贵时间阅读本文。非常感谢。

2 个答案:

答案 0 :(得分:0)

  

如果我的假设是正确的,这是否意味着如果套接字是非阻塞的,那么SSL也是如此?

  

默认情况下winsock tcp套接字是非阻塞的(假设我已经创建了一个TCP套接字,但没有调用ioctlsocket并设置非阻塞模式)

Unix套接字默认是阻塞的。没用过Winsock。但我确定Winsock应默认阻止。

答案 1 :(得分:0)

尝试以下代码:

   SSL_set_fd(ss, sock);
retry:
   int ret = SSL_accept(ssl);
   if (ret != 1) {
      int err = SSL_get_error(ssl, ret);
      if (err == SSL_ERROR_WANT_READ || SSL_ERROR_WANT_WRITE) {
         // maybe need some sleep or select
         goto retry;
      }
   }