* nix中和放大器; C ++写一个非阻塞套接字服务器 [英] *nix & C++ writing a non-blocking socket server

查看:144
本文介绍了* nix中和放大器; C ++写一个非阻塞套接字服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了我的阻止套接字服务器重写非阻塞版本的一些问题。
其实,我似乎无法连得插座连接了,我一直在使用Google的最今天,并尝试不同的解决方案,我觉得在这里和那里,但他们都不能够正常工作...
目前我的服务器循环只是不断timeouting的select()调用,以接受没有新的插槽。
客户端套接字似乎在一定程度上进行连接,因为如果我启动它,它会阻止试图写,如果我关闭服务器,它会通知连接被对方​​复位。

在下面的一个正确的假设?
与非阻塞服务器,我应该常开插座,然后将其设置的标志,以无阻塞,将其绑定,并开始呼吁选择读文件描述符,等待它来填充?
我需要删除旧堵接受()称,这是无休止地等待..
如果我尝试调用接受,现在它将-1我...

下面是相关code现在我试图

  FD_SET incoming_sockets;
....
INT listener_socket,newsockfd,PORTNO;
socklen_t的clilen;
结构SOCKADDR_IN serv_addr,cli_addr;
....
listener_socket =插座(AF_INET,SOCK_STREAM,0); //获取套接字句柄
INT标志=的fcntl(listener_socket,F_GETFL,0);
如果(的fcntl(listener_socket,F_SETFL,旗帜| O_NONBLOCK)℃下)
    log_writer-> write_to_error_log(错误设置监听套接字非阻塞,FALSE);
memset的(安培; serv_addr,0,sizeof的(结构SOCKADDR_IN));serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORTNO);
....
如果(绑定(listener_socket,(结构sockaddr *)及serv_addr,
        的sizeof(结构SOCKADDR_IN))< 0)
{
    log_writer-> write_to_error_log(无法绑定套接字,中止!,真正的);
}
....
timeval结构超时;
timeout.tv_sec = 1;
timeout.tv_usec = 0;INT ready_sockets = 0;听(listener_socket,1);FD_ZERO(安培; incoming_sockets);
FD_SET(listener_socket,&安培; incoming_sockets);而(真)
{ready_sockets =选择(listener_socket + 1,&安培; incoming_sockets,(FD_SET *)0,(FD_SET *)0,和放大器;超时);如果(ready_sockets == 0)
    {
        //我现在在这里循环永远
        性病::法院LT&;< 没有新插座,贪睡2 \\ N的;
        睡眠(2);
    }其他
    {
    性病::法院LT&;< 连接接收\\ N!


解决方案

既然你不显示整个循环,我不知道如果以后做,但你应该每前初始化描述符集和超时结构来电选择

I'm experiencing some issues with rewriting my blocking socket server to a non-blocking version. Actually, I can't seem to even get socket connected anymore, I've been googling for the most of today, and trying different solutions I find here and there, but none of them seem to work properly... Currently my server loop just keeps timeouting the select() call, with no new sockets accepted. Client socket seems to connect on some level, since if I start it, it will block trying to write, and if I close the server, it will inform that connection was reset by peer.

Is the following a correct assumption? With non-blocking server I should normally open the socket, then set it's flags to non-blocking, bind it, and the start calling select for read file descriptor and wait for it to populate ? I need to remove old blocking "accept()" call, which was waiting endlessly.. If I try calling accept, it will -1 on me now...

Here is the relevant code I'm trying now

fd_set incoming_sockets;
....
int listener_socket, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
....
listener_socket = socket(AF_INET, SOCK_STREAM, 0); //get socket handle
int flags = fcntl(listener_socket, F_GETFL, 0);
if( fcntl(listener_socket, F_SETFL, flags | O_NONBLOCK) < 0 )
    log_writer->write_to_error_log("Error setting listening socket to non blocking", false);
memset(&serv_addr, 0, sizeof(struct sockaddr_in));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
....
if (bind(listener_socket, (struct sockaddr *) &serv_addr,
        sizeof(struct sockaddr_in)) < 0)
{
    log_writer->write_to_error_log("Unable to bind socket, aborting!", true);
}
....
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;

int ready_sockets = 0;

listen(listener_socket,1);

FD_ZERO(&incoming_sockets); 
FD_SET(listener_socket, &incoming_sockets); 

while(true)
{

ready_sockets = select(listener_socket + 1 , &incoming_sockets, (fd_set * ) 0, (fd_set * ) 0, &timeout  );

if(ready_sockets == 0)
    {
        //I loop here now for ever
        std::cout << "no new sockets available, snooze 2\n";
        sleep(2);
    } else
    {
    std::cout << "connection received!\n";

解决方案

Since you don't show the whole loop, I don't know if you do it later, but you should initialize the descriptor sets and timeout structure before every call to select.

这篇关于* nix中和放大器; C ++写一个非阻塞套接字服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆