【发布时间】:2016-08-20 21:02:33
【问题描述】:
我正在用 C 语言编写一个小的 IRC 机器人,使用 openssl 来启动一个安全套接字。它不是写得最漂亮的机器人,但主要是为了看看 openssl API 是如何工作的。目前我有以下代码:
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
int main() {
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
BIO *bio;
SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());
SSL * ssl;
SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs/");
bio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(bio, & ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
BIO_set_nbio(bio, 1);
BIO_set_conn_hostname(bio, "irc.freenode.net:6697");
BIO_do_connect(bio);
if(SSL_get_verify_result(ssl) != X509_V_OK) {
printf("error\n");
}
char irc1[] = "NICK bartender\r\n";
char irc2[] = "USER bartender * * :serve(&drinks);\r\n";
BIO_write(bio, irc1, strlen(irc1));
BIO_write(bio, irc2, strlen(irc2));
fd_set read_set;
int sock = BIO_get_fd(bio, NULL);
while(1) {
FD_ZERO(&read_set);
FD_SET(sock, &read_set);
struct timeval timeout = { 0, 0 };
select(sock+1, &read_set, NULL, NULL, &timeout);
if(FD_ISSET(sock, &read_set)) {
char buf[21];
size_t x = BIO_read(bio, buf, 20);
if(x == 0) {
continue;
} else if(x == -1){
int code = ERR_get_error();
if(code == 0) {
continue;
}
printf("(%d)%s\n", code, ERR_error_string(code, NULL));
} else {
buf[x] = '\0';
printf("%s", buf);
}
}
}
}
每当我编译和运行这段代码时,它都会挂起并且什么也不打印。但是,如果我删除第 20 行(当前将套接字置于非阻塞模式),它工作正常。为什么将套接字置于非阻塞模式会导致这种行为?谢谢你,祝你有美好的一天!
【问题讨论】:
-
您不能只是将任何套接字更改为 Jon 阻塞模式并期望相同的代码继续工作。还有更多工作要做,在 SSL 套接字的情况下还有很多工作要做。请参阅 OpenSSL 文档。太宽泛了。
-
我看不出“将 BIO 对象置于非阻塞模式”是多么的宽泛。我确信还有更多工作要做,否则它会起作用。需要做什么?我已经阅读了 openssl 手册页,并咨询了 google 和以前的 SO 答案。我找不到其他需要做的事情。
-
还有很多工作要做,所有这些都记录在 man select 和 OpenSSL 文档中,在这里无法回答。跨度>
-
它不是。我已经完成了选择所需的一切。如果给出简短的答案,显然不会太宽泛。
标签: c ssl network-programming openssl