如果winsock2套接字是非阻塞的,那么与它关联的SSL对象是否也会显示非阻塞行为?

问题描述:

我在问这个问题,因为我不确定SSL对象是否将套接字视为消息的接收器/消息源,就像它对BIO对象所做的一样。我的直觉告诉我是的,但我不确定。如果winsock2套接字是非阻塞的,那么与它关联的SSL对象是否也会显示非阻塞行为?

目标: 我正在将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]中,SSL是非阻塞如果底层BIO是非阻塞的。如果我的假设是正确的,这是否意味着如果套接字是非阻塞的,SSL也是如此?

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

感谢您参加读这个的时候。非常感谢。

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

是的。

默认情况下,一个Winsock TCP套接字非阻塞(假设我已经创建了一个TCP套接字,但不叫ioctlsocket并设置非阻塞模式)

Unix套接字默认为阻塞。没有使用Winsock。但是肯定Winsock应该是默认阻塞的。

+0

感谢。 winsock是与Unix套接字库等效的Windows库。 – GloriousLemon

+0

默认情况下,Winsock套接字确实会阻塞*。 –

试试下面的代码:

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

你可以在你的答案中解释为什么它会起作用吗? – Zulu