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
C++ 在同时运行多个连接时,我会强烈建议您在考虑边缘触发之前掌握级别触发的使用。即使这样,我也不会费心,我确实删除了accept循环,因为它看起来很愚蠢;甚至不知道这个例子为什么会有这样的结果。(我知道,为什么,这也很愚蠢。)不幸的是,再加上移除边缘触发并立即调_C++_Sockets_Epoll - Fatal编程技术网

C++ 在同时运行多个连接时,我会强烈建议您在考虑边缘触发之前掌握级别触发的使用。即使这样,我也不会费心,我确实删除了accept循环,因为它看起来很愚蠢;甚至不知道这个例子为什么会有这样的结果。(我知道,为什么,这也很愚蠢。)不幸的是,再加上移除边缘触发并立即调

C++ 在同时运行多个连接时,我会强烈建议您在考虑边缘触发之前掌握级别触发的使用。即使这样,我也不会费心,我确实删除了accept循环,因为它看起来很愚蠢;甚至不知道这个例子为什么会有这样的结果。(我知道,为什么,这也很愚蠢。)不幸的是,再加上移除边缘触发并立即调,c++,sockets,epoll,C++,Sockets,Epoll,在同时运行多个连接时,我会强烈建议您在考虑边缘触发之前掌握级别触发的使用。即使这样,我也不会费心,我确实删除了accept循环,因为它看起来很愚蠢;甚至不知道这个例子为什么会有这样的结果。(我知道,为什么,这也很愚蠢。)不幸的是,再加上移除边缘触发并立即调用我的接收函数,并没有影响结果。@DigitalMan-我刚刚更新了这个答案(因为我点击了“post”太快了。请再读一遍。在任何情况下,我都在使用我自己的TCP套接字应用程序中的ePoLo,我只是在前几天工作。当我看到我的代码有同样的bug时,


在同时运行多个连接时,我会强烈建议您在考虑边缘触发之前掌握级别触发的使用。即使这样,我也不会费心,我确实删除了accept循环,因为它看起来很愚蠢;甚至不知道这个例子为什么会有这样的结果。(我知道,为什么,这也很愚蠢。)不幸的是,再加上移除边缘触发并立即调用我的接收函数,并没有影响结果。@DigitalMan-我刚刚更新了这个答案(因为我点击了“post”太快了。请再读一遍。在任何情况下,我都在使用我自己的TCP套接字应用程序中的ePoLo,我只是在前几天工作。当我看到我的代码有同样的bug时,我有点恐慌。但是,它似乎处理好多个连接。在这种情况下,通信需要保持同步。它是同步的,因此它会立即发送,而不是冒着某些东西妨碍或发送顺序错误的风险。它被设置为记录发送错误,到目前为止从未记录过。我删除了accept循环,因为这只是“更好”如果它在同一纳秒内接收到两个连接,我对此表示怀疑。但是,已经发现,删除边缘触发确实会导致处理按预期来回反弹。一个客户端仍然挂起,但现在问题应该更加孤立。@DigitalMan-如果通信需要保持同步,那么为什么要同时处理多个连接呢?1)epoll最初是为边缘触发使用而设计的,我完全理解它的工作原理,因为它很有意义。2,3,4,已经完成了,因为这也是有意义的。到目前为止,发送从未失败或碰到过eWolfBlock-如果失败,我将设计一些系统来处理它,但在它发生之前我不会这么做。欢迎您将其用作边缘触发设备,只是不要指定
ePllet
标志。它仍然会在每一个边缘触发。如果你错过了一个信号,它不会死掉。在你关闭它之前,先从
epoll
集合中取出插座。为什么?我看不出有什么区别,遇到错误时总是尽快关闭/关闭套接字。@Zind:关闭套接字不会将其从
epoll
集中删除,关闭它只会在关闭最后一个引用时将其删除。@DavidSchwartz:(1)关闭/关闭套接字。(2) 从
epoll
集合中卸下插座。我执行这两个操作,我想你的意思是这两个操作的顺序很重要。哦,该死,你说得对!天哪,我真是个白痴。我修好了,它运行得很好!好的一面是,至少我的边缘触发实现在整个过程中都是正确的。
#define EVENTMODE (EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLHUP)
#define ERRCHECK (EPOLLERR | EPOLLHUP | EPOLLRDHUP)

//Setup event buffer:
struct epoll_event* events = (epoll_event*)calloc(maxEventCount, sizeof(event));

//Setup done, main processing loop:
int iter, eventCount;
while (1) {

    //Wait for events indefinitely:
    eventCount = epoll_wait(pollID, events, maxEventCount, -1);
    if (eventCount < 0) {
        syslog(LOG_ERR, "Poll checking error, continuing...");
        continue;
    }
    for (iter = 0; iter<eventCount; ++iter) {
        int currFD = events[iter].data.fd;
        cout << "Working with " << events[iter].data.fd << endl;
        if (events[iter].events & ERRCHECK) {
            //Error or hangup:
            cout << "Closing " << events[iter].data.fd << endl;
            close(events[iter].data.fd);
            continue;
        } else if (!(events[iter].events & EPOLLIN)) {
            //Data not really ready?
            cout << "Not ready on " << events[iter].data.fd << endl;
            continue;
        } else if (events[iter].data.fd == socketID) {
            //Event on the listening socket, incoming connections:
            cout << "Connecting on " << events[iter].data.fd << endl;

            //Set up accepting socket descriptor:
            int acceptID = accept(socketID, NULL, NULL);
            if (acceptID == -1) {
                //Error:
                if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
                    //NOT just letting us know there's nothing new:
                    syslog(LOG_ERR, "Can't accept on socket: %s", strerror(errno));
                }
                continue;
            }
            //Set non-blocking:
            if (setNonBlocking(acceptID) < 0) {
                //Error:
                syslog(LOG_ERR, "Can't set accepting socket non-blocking: %s", strerror(errno));
                close(acceptID);
                continue;
            }
            cout << "Listening on " << acceptID << endl;
            //Add event listener:
            event.data.fd = acceptID;
            event.events = EVENTMODE;
            if (epoll_ctl(pollID, EPOLL_CTL_ADD, acceptID, &event) < 0) {
                //Error adding event:
                syslog(LOG_ERR, "Can't edit epoll: %s", strerror(errno));
                close(acceptID);
                continue;
            }

        } else {
            //Data on accepting socket waiting to be read:
            cout << "Receive attempt on " << event.data.fd << endl;
            cout << "Supposed to be " << currFD << endl;
            if (receive(event.data.fd) == false) {
                sendOut(event.data.fd, streamFalse);
            }
        }
    }
}
bool receive(int socketID)
{
short recLen = 0;
char buff[BUFFERSIZE];
FixedByteStream received;
short fullSize = 0;
short diff = 0;
short iter = 0;
short recSoFar = 0;

//Loop through received buffer:
while ((recLen = read(socketID, buff, BUFFERSIZE)) > 0) {
    cout << "Receiving on " << socketID << endl;
    if (fullSize == 0) {
        //We don't know the size yet, that's the first two bytes:
        fullSize = ntohs(*(uint16_t*)&buff[0]);
        if (fullSize < 4 || recLen < 4) {
            //Something went wrong:
            syslog(LOG_ERR, "Received nothing.");
            return false;
        }
        received = FixedByteStream(fullSize);
    }
    diff = fullSize - recSoFar;
    if (diff > recLen) {
        //More than received bytes left, get them all:
        for (iter=0; iter<recLen; ++iter) {
            received[recSoFar++] = buff[iter];
        }
    } else {
        //Less than or equal to received bytes left, get only what we need:
        for (iter=0; iter<diff; ++iter) {
            received[recSoFar++] = buff[iter];
        }
    }
}
if (recLen < 0 && errno == EWOULDBLOCK) {
    cout << "Would block on " << socketID << endl;
}
if (recLen < 0 && errno != EWOULDBLOCK) {
    //Had an error:
    cout << "Error on " << socketID << endl;
    syslog(LOG_ERR, "Connection receive error: %s", strerror(errno));
    return false;
} else if (recLen == 0) {
    //Nothing received at all?
    cout << "Received nothing on " << socketID << endl;
    return true;
}
if (fullSize == 0) {
    return true;
}

//Store response, since it needs to be passed as a reference:
FixedByteStream response = process(received);
//Send response:
sendOut(socketID, response);
return true;
}
bool sendOut(int socketID, FixedByteStream &output)
{
cout << "Sending on " << socketID << endl;
//Send to socket:
if (write(socketID, (char*)output, output.getLength()) < 0) {
    syslog(LOG_ERR, "Connection send error: %s", strerror(errno));
    return false;
}

return true;
}