Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 套接字::接受继续返回EGAIN_Linux_Sockets - Fatal编程技术网

Linux 套接字::接受继续返回EGAIN

Linux 套接字::接受继续返回EGAIN,linux,sockets,Linux,Sockets,我使用非阻塞套接字来接收新连接。但代码多次无法接受() int-sockfd=::socket(系列,SOCK_流| SOCK_非块| SOCK_CLOEXEC,IPPROTO_TCP); ::绑定(sockfd,bind_addr,static_cast(sizeof(struct sockaddr_in6)); ret=::监听(sockfd,SOMAXCONN); while(True){ ::轮询(&*pollfds_uu.begin(),pollfds_uu.size(),timeou

我使用非阻塞套接字来接收新连接。但代码多次无法接受()

int-sockfd=::socket(系列,SOCK_流| SOCK_非块| SOCK_CLOEXEC,IPPROTO_TCP);
::绑定(sockfd,bind_addr,static_cast(sizeof(struct sockaddr_in6));
ret=::监听(sockfd,SOMAXCONN);
while(True){
::轮询(&*pollfds_uu.begin(),pollfds_uu.size(),timeoutMs);
6地址中的结构sockaddr_;
bzero(地址和地址,地址大小);
socklen\u t addrlen=静态演员阵容(sizeof*addr);
int connfd=::accept4(sockfd,sockaddr_cast(addr),
&addrlen,SOCK_NONBLOCK | SOCK_CLOEXEC);
}

errno
EAGAIN
从手册页到
accept(2)

伊根或伊沃块

插座标记为非阻塞,不存在可接受的连接。POSIX.1-2001允许在这种情况下返回任一错误,并且不要求这些常量具有相同的值,因此便携式应用程序应该检查这两种可能性


这意味着对
接受的调用是在客户端连接之前进行的。

从手册页到
接受(2)

伊根或伊沃块

插座标记为非阻塞,不存在可接受的连接。POSIX.1-2001允许在这种情况下返回任一错误,并且不要求这些常量具有相同的值,因此便携式应用程序应该检查这两种可能性


这意味着对
accept
的调用是在客户端连接之前进行的。

在调用
accept
之前,必须调用
listen
bind
但是由于套接字没有阻塞,您应该等待客户端等待连接。您可以使用
select
功能:

int sockfd = ::socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);

// addr is for accept call, sin for bind call
struct sockaddr_in6 addr, sin;
bzero(&addr, sizeof addr);

// prepare sin to tell bind to listen on any connection on given port
sin.sin6_family = family;
sin.sin6_addr = in6addr_any;
sin.sin6_port = htons(port); // choose port on which client could connect
sin.sin6_scope_id = 0;

// bind socket to interface
if (::bind(sock, (struct sockaddr*) &sin, sizeof(sin)) < 0)
{
    perror("bind");
}

// listen for new connection
if (::listen(sock, SOMAXCONN) < 0)
{
    perror("socket");
}

while (1)
{
    fd_set conset;
    FD_ZERO(&conset); 
    FD_SET(sockfd, &conset);

    struct timeval timeout = {10, 0};
    int maxfd = sockfd;

    // wait for new client
    select(maxfd + 1, &conset, NULL, NULL, &timeout);

    if (FD_ISSET(sockfd, &conset))
    {
        // a new client is waiting
        int connfd = ::accept(sockfd, &addr);
        if (connfd < 0)
        {
            perror("accept");
        }
        else
        {
            // do thing with new client
        }
    }
    else
    {
        printf("no new client in last 10 seconds")
    }
}
int-sockfd=::socket(系列,SOCK_流| SOCK_非块| SOCK_CLOEXEC,IPPROTO_TCP);
//addr表示接受调用,sin表示绑定调用
结构sockaddr_in 6 addr,sin;
bzero(地址和地址,地址大小);
//准备sin,让bind监听给定端口上的任何连接
sin.sin6_family=家庭;
sin.sin6_addr=in6addr_any;
sin.sin6_port=htons(port);//选择客户端可以连接的端口
sin.sin6_scope_id=0;
//将套接字绑定到接口
if(::bind(sock,(struct sockaddr*)&sin,sizeof(sin))<0)
{
佩罗(“绑定”);
}
//监听新的连接
if(::侦听(sock、SOMAXCONN)<0)
{
佩罗(“插座”);
}
而(1)
{
fd_集conset;
FD_零(和conset);
FD_集(sockfd和conset);
struct timeval timeout={10,0};
int maxfd=sockfd;
//等待新客户
选择(maxfd+1,&conset,NULL,NULL,&timeout);
if(FD_ISSET(sockfd和conset))
{
//新客户正在等待
int connfd=::接受(sockfd,&addr);
如果(connfd<0)
{
佩罗(“接受”);
}
其他的
{
//与新客户打交道
}
}
其他的
{
printf(“过去10秒内没有新客户端”)
}
}

在调用
accept
之前,必须调用
listen
bind
但是由于套接字没有阻塞,您应该等待客户端等待连接。您可以使用
select
功能:

int sockfd = ::socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);

// addr is for accept call, sin for bind call
struct sockaddr_in6 addr, sin;
bzero(&addr, sizeof addr);

// prepare sin to tell bind to listen on any connection on given port
sin.sin6_family = family;
sin.sin6_addr = in6addr_any;
sin.sin6_port = htons(port); // choose port on which client could connect
sin.sin6_scope_id = 0;

// bind socket to interface
if (::bind(sock, (struct sockaddr*) &sin, sizeof(sin)) < 0)
{
    perror("bind");
}

// listen for new connection
if (::listen(sock, SOMAXCONN) < 0)
{
    perror("socket");
}

while (1)
{
    fd_set conset;
    FD_ZERO(&conset); 
    FD_SET(sockfd, &conset);

    struct timeval timeout = {10, 0};
    int maxfd = sockfd;

    // wait for new client
    select(maxfd + 1, &conset, NULL, NULL, &timeout);

    if (FD_ISSET(sockfd, &conset))
    {
        // a new client is waiting
        int connfd = ::accept(sockfd, &addr);
        if (connfd < 0)
        {
            perror("accept");
        }
        else
        {
            // do thing with new client
        }
    }
    else
    {
        printf("no new client in last 10 seconds")
    }
}
int-sockfd=::socket(系列,SOCK_流| SOCK_非块| SOCK_CLOEXEC,IPPROTO_TCP);
//addr表示接受调用,sin表示绑定调用
结构sockaddr_in 6 addr,sin;
bzero(地址和地址,地址大小);
//准备sin,让bind监听给定端口上的任何连接
sin.sin6_family=家庭;
sin.sin6_addr=in6addr_any;
sin.sin6_port=htons(port);//选择客户端可以连接的端口
sin.sin6_scope_id=0;
//将套接字绑定到接口
if(::bind(sock,(struct sockaddr*)&sin,sizeof(sin))<0)
{
佩罗(“绑定”);
}
//监听新的连接
if(::侦听(sock、SOMAXCONN)<0)
{
佩罗(“插座”);
}
而(1)
{
fd_集conset;
FD_零(和conset);
FD_集(sockfd和conset);
struct timeval timeout={10,0};
int maxfd=sockfd;
//等待新客户
选择(maxfd+1,&conset,NULL,NULL,&timeout);
if(FD_ISSET(sockfd和conset))
{
//新客户正在等待
int connfd=::接受(sockfd,&addr);
如果(connfd<0)
{
佩罗(“接受”);
}
其他的
{
//与新客户打交道
}
}
其他的
{
printf(“过去10秒内没有新客户端”)
}
}

你定义了两次
connfd
,你能发布一个吗?你是使用ipv6(
sockaddr\u in6
)还是ipv4(
::accept4
)?@purplepsycho我从我的项目中再复制一行。@purplepsycho我使用ipv4。sockaddr\u in6与ivp4兼容。您是否考虑过检查
poll()
的结果或事件集,而不是盲目地假设套接字已变得可读?您定义了
connfd
两次,是否可以发布一个消息?您是否使用ipv6(
sockaddr\u in6
)或ipv4(
::accept4
)?@purplepsycho我从项目中再复制一行。@purplepsycho我使用ipv4。sockadd_in6与ivp4兼容。您是否考虑过检查
poll()
的结果或事件集,而不是盲目地假设套接字已变得可读?之前的代码只是要点。我有投票的粘贴代码。前面的代码只是要点。我有投票的粘贴代码。