我有一个使用多个阻塞套接字的服务器线程,当需要处理数据时我需要它运行。问题是,我如何让OpenSSL做到“它的东西”(如重新协商)而不会陷入阻塞操作(等待应用程序数据)?注意:我有SSL_set_mode - SSL_MODE_AUTO_RETRY
,我怀疑我不需要这样做,并且自己处理这些案例,但是从阅读文档中我不清楚我该如何实现这一点。请看下面的伪代码:使用select和多个阻塞套接字的OpenSSL重新协商
while(running){
select on readability sockets 1 and 2
if(socket 1 readable) {
SSL_read data(socket 1)
process data, possibly interacting with socket 2
}
if(socket 2 readable) {
SSL_read data(socket 2)
process data, possibly interacting with socket 1
}
}
如果选择滴出,因为有SSL/TLS层“要做的事情”或者插座上,但没有应用层数据,会发生什么? SSL_read
将处理“要做的事情”,但之后会因为没有应用程序数据而阻塞......该块会阻止从另一个套接字读取数据的能力。有很好的方法SSL_pending
可以告诉我关于应用程序的数据,但是据我所知,堆栈没有机会获得任何没有SSL_read
的数据。除了将套接字分成单独的线程或使用非阻塞套接字之外,是否有一种简单方法可以向OpenSSL层说几句话,如“如果需要,请重新协商,并在有数据记录的情况下读取数据记录,但不要阻止如果不需要“?像NULL/NULL读取或写入?
// process records on the socket
SSL_read(ssl, 0, 0); // or maybe SSL_write(ssl, 0, 0) ?
if (SSL_pending(ssl)) {
// do the application data read
SSL_read(ssl, buf, sizeof(buf));
}
编辑:尝试了做SSL_read(ssl, 0, 0)
没有选择读和阻塞的记录,以便将无法工作。做选择然后读取0/0或SSL_write(ssl, 0, 0)
没有选择似乎不被阻止,虽然我还不确定是否正在做我所需要的事情...
SSL_Pending用于预读,而不是用于您正在使用的目的。当完成下一次读取时,阻塞读取将自动重新协商。如果您使用的是ssl_set_fd,则可以在描述符上设置接收超时值,在这种情况下它可能会有所帮助。 http://stackoverflow.com/questions/4181784/how-to-set-socket-timeout-in-c-when-making-multiple-connections。否则可以使用非阻塞io。 –