【发布时间】:2017-11-14 08:16:26
【问题描述】:
我在 OpenSSL 连接中使用阻塞套接字。 SSL_read 有时会阻塞几秒钟。在服务器中 - BIO_write 用于以可变缓冲区大小发送数据。在客户端 - 第一个 SSL_read 获取缓冲区大小成功,但随后 SSL_read 获取缓冲区数据块几秒钟(此问题在 2 到 3 分钟后模拟),即使数据发送成功。我等待 poll() 调用客户端读取功能。如何纠正这些阻塞套接字的问题?
服务器代码
void process_and_send() {
// sending variable size buffer each time
// sbuf - first 4 bytes contains sbuf size information
send_data(sbuf, sbufSize);
}
void send_data(void *sbuf, int pending_len) {
while(pending_len > 0) {
result = BIO_write(bio, sbuf, pending_len);
if(result == 0) {
attempts = 0;
LOG_D("%s", log_str(SSL_CONN_CLOSE));
SSL_FN_TRACE("connection closed\n");
break;
}
else if(result < 0) {
LOG_I("%s", log_str(SSL_WRITE_FAIL));
SSL_FN_TRACE("BIO_write fail\n");
if(errno == EINTR) {
continue;
}
if(errno == EAGAIN) {
attempts++;
continue;
}
if(errno == EWOULDBLOCK) {
attempts++;
continue;
}
break;
}
else {
BIO_flush(bio);
pending_len -= result;
sbuf += result;
}
}
}
客户代码
// wait on poll() and call receive_and_process
void receive_and_process() {
int rbufSize = 0;
// get the size of data to read
receive_data((void *)&rbufSize, sizeof(Int));
// this call blocks for few seconds
receive_data(rbuf, rbufSize);
}
void receive_data(void *rbuf, int pending_len) {
while(pending_len > 0) {
result = SSL_read(ssl, rbuf, pending_len);
if(result == 0) {
LOG_D("%s", log_str(SSL_CONN_CLOSE));
SSL_FN_TRACE("connection closed\n");
return NULL;
}
else if(result < 0) {
if(errno == ETIMEDOUT) {
SSL_FN_ERROR("SSL read timeout: \n");
continue;
}
if(errno == EINTR) {
continue;
}
if(errno == EAGAIN) {
continue;
}
if(errno == EWOULDBLOCK) {
continue;
}
SSL_FN_ERROR("SSL read fail error no: %s\n",
ERR_reason_error_string(ERR_get_error()));
LOG_I("%s", log_str(SSL_READ_FAIL));
return NULL;
}
pending_len -= result;
rbuf += result;
FN_ERROR("after read full data pending len %d\n", pending_len);
}
}
【问题讨论】:
-
我同意。通过阻塞套接字阻塞的 I/O。你的问题?
-
为什么会阻塞?即使数据发送成功。
标签: sockets ssl openssl blocking