我使用sys / socket和OpenSSL设置了一个简单的套接字服务器。对于每个连接,客户端都需要向服务器发送消息,接收响应,然后回复该响应。
我找不到任何明确的机制来使这些套接字无阻塞?系统必须能够同时处理多个套接字......
我的服务器代码,用于侦听连接:
while(1)
{
struct sockaddr_in addr;
uint len = sizeof(addr);
SSL *ssl;
int client = accept(sock, (struct sockaddr*)&addr, &len);
if (client > 0)
{
std::cout<<"Client accepted..."<<std::endl;
}
else
{
perror("Unable to accept");
exit(EXIT_FAILURE);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client);
if (SSL_accept(ssl) <= 0)
{
std::cout<<"ERROR"<<std::endl;
}
else
{
char buff[1024];
SSL_read(ssl, buff, 1024);
std::cout<<buff<<std::endl;
std::string reply="Thanks from the server";
char buff_response[1024];
reply.copy(buff_response, 1024);
const void *buf=&buff_response;
SSL_write(ssl, buf, 1024);
char another_buff[1024];
SSL_read(ssl,another_buff,1024);
std::cout<<another_buff<<std::endl;
}
}
我已经研究过'select()',但是这似乎不允许并发,但允许系统知道何时释放套接字?
有没有人有解决这个基本问题的经验?
答案 0 :(得分:1)
首先,使用服务器代码,differentiate between concurrency and parallelism非常重要。合理的服务器通常会处理many more connections concurrently than its number of cores。因此,使代码并发非常重要,因为它可以(有效地)处理许多并发连接,其方式不依赖于并行 (在一个线程处理每个连接的意义上)。
从这个意义上讲,select
实际上是并发的合理选择,并为您提供the effect of being non-blocking。
当您的系统同时处理多个套接字时,select
指示您可以执行哪些套接字,例如send
和recv
,而不会阻止它们执行此操作。如果你很好地使用select
,你就不会遇到线程空闲的情况,无限期地等待某些操作继续进行,而其他套接字已准备好。
minimal example from gnu.org显示了一个合理有效的服务器,它似乎可以适应您的需求。
fd_set active_fd_set, read_fd_set;
FD_ZERO (&active_fd_set);
FD_ZERO (&read_fd_set);
// Use FD_SET to add sockets according to what you want to do with them
/* This call (checking to see who can be read) is the
* only thing that blocks. But if it does, no socket is ready for reading. */
if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
// Handle error;
for (i = 0; i < FD_SETSIZE; ++i)
if (FD_ISSET (i, &read_fd_set))
// Here you can read without its blocking.