[英]Non-blocking connect OpenSSL
我創建了一個常規的C套接字。 連接后,它按預期返回EWOULDBLOCK/WSAEWOULDBLOCK
,因為我這樣做了:
unsigned long int mode = 0;
ioctlsocket(ssl_info->sock, FIONBIO, &mode);
setsockopt(ssl_info->sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
setsockopt(ssl_info->sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
將套接字置於非阻塞模式。 之后,我要做:
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
return SSL_connect(ssl);
但是,它返回-1。
我在網上閱讀這意味着我需要處理SSL_ERROR_WANT_READ
和SSL_ERROR_WANT_WRITE
。
所以我做了:
int res = -1;
while(res == -1)
{
res = SSL_connect(ssl);
switch (SSL_get_error(ssl, res))
{
case SSL_ERROR_WANT_CONNECT:
MessageBox(NULL, "Connect Error", "", 0);
break;
case SSL_ERROR_WANT_READ: //prints this every time..
MessageBox(NULL, "Read Error", "", 0);
break;
case SSL_ERROR_WANT_WRITE:
MessageBox(NULL, "Write Error", "", 0);
break;
}
SelectSocket(ssl);
}
std::cout<<"Connected!\n";
其中SelectSocket
定義為:
bool SelectSocket(SSL* ssl)
{
if (blockmode)
{
fd_set readfds;
fd_set writefds;
FD_ZERO(&readfds);
FD_ZERO (&writefds);
FD_SET(ssl_info->sock, &readfds);
FD_SET(ssl_info->sock, &writefds);
struct timeval tv = {0};
tv.tv_sec = timeout / 1000;
tv.tv_usec = timeout % 1000;
return select(sock + 1, &readfds, &writefds, NULL, &tv) >= 0;
}
return select(sock + 1, NULL, NULL, NULL, NULL) != SOCKET_ERROR;
}
那么我如何才能使其連接呢? 當套接字是非阻塞的:S時,我似乎無法讀取或寫入任何內容。
有任何想法嗎?
SSL_connect()返回的(-1)表示基礎BIO無法滿足SSL_connect()繼續握手的需求。
通常,調用過程然后必須采取適當的措施以滿足SSL_connect()的需要后重復該調用。
但是,當使用非阻塞套接字時,什么也不做; 但是select()可用於檢查所需條件。
(當使用緩沖BIO(如BIO對)時,必須先將數據寫入BIO或從中檢索出數據,然后才能繼續。)
您的代碼實際上禁用了非阻塞I / O。 當您將0作為FIONBIO的參數值傳遞給ioctlsocket時,記錄為:
菲奧比奧
* argp參數是一個指向無符號long值的指針。 如果應啟用 非阻塞模式,則將* argp設置為非零值;如果應禁用非阻塞模式,則將* argp設置為零 。 [..]
https://msdn.microsoft.com/zh-CN/library/windows/desktop/ms738573%28v=vs.85%29.aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.