C++ select 停止接受连接

标签 c++ windows sockets select


我正在尝试创建一个选择服务器以接收来自多个客户端的连接(所有客户端都将连接到同一端口)。
服务器接受前 2 个客户端,但除非其中一个断开连接,否则它不会接受新的客户端。 我开始像这样监听服务器端口:

listen(m_socketId, SOMAXCONN);  

并像这样使用选择命令:

int selected = select(m_maxSocketId + 1, &m_socketReadSet, NULL, NULL, 0);

我添加了一些代码。

bool TcpServer::Start(char* ipAddress, int port)
{
    m_active = true;
    FD_ZERO(&m_socketMasterSet);
    bool listening = m_socket->Listen(ipAddress, port);
    // Start listening.

    m_maxSocketId = m_socket->GetId();
    FD_SET(m_maxSocketId, &m_socketMasterSet);
    if (listening == true)
    {
        StartThread(&InvokeListening);
        StartReceiving();
        return true;
    }
    else
    {
        return false;
    }
}

void TcpServer::Listen()
{
    while (m_active == true)
    {
        m_socketReadSet = m_socketMasterSet;
        int selected = select(m_maxSocketId + 1, &m_socketReadSet, NULL, NULL, 0);
        if (selected <= 0)
            continue;
        bool accepted = Accept();
        if (accepted == false)
        {
            ReceiveFromSockets();
        }
    }
}

bool TcpServer::Accept()
{
    int listenerId = m_socket->GetId();
    if (FD_ISSET(listenerId, &m_socketReadSet) == true)
    {
        struct sockaddr_in remoteAddr;
        int addrSize = sizeof(remoteAddr);
        unsigned int newSockId = accept(listenerId, (struct sockaddr *)&remoteAddr, &addrSize);
        if (newSockId == -1) // Invalid socket...
        {
            return false;
        }
        if (newSockId > m_maxSocketId)
        {
            m_maxSocketId = newSockId;
        }

        m_clientUniqueId++;
        // Remembering the new socket, so we'll be able to check its state
        // the next time.
        FD_SET(newSockId, &m_socketMasterSet);

        CommEndPoint remote(remoteAddr);
        CommEndPoint local = m_socket->GetLocalPoint();

        ClientId* client = new ClientId(m_clientUniqueId, newSockId, local, remote);
        m_clients.Add(client);
        StoreNewlyAcceptedClient(client);
        char acceptedMsg = CommInternalServerMsg::ConnectionAccepted;
        Server::Send(CommMessageType::Internal, client, &acceptedMsg, sizeof(acceptedMsg));
        return true;
    }

    return false;
}

我希望这足够了:) 有什么问题吗?

最佳答案

到目前为止,select() 最常见的错误是没有在每次迭代时重新初始化 fd 集。第二个、第三个和第四个参数通过调用更新,因此您必须每次再次填充它们。

发布更多代码,这样人们才能真正帮助您。

编辑0:

fd_set在 Windows 上是一团糟:)

关于C++ select 停止接受连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6083758/

相关文章:

c++ - 在 Qt 的 emit() 中传递指向自身的指针

android - WifiP2pInfo.groupOwnerAddress.getHostAddress() IP 错误

C++:互斥锁从通知程序到服务员的传递是无缝的吗?

java - 什么是 "typing models"?

python - 如何在 Windows 下用 Python 将表情符号渲染为图像?

windows - 以编程方式(而非手动)查找 Git 在 Windows 系统上的安装路径

c - 将c程序从linux迁移到windows

android - 使用Socket编程android的聊天应用

python - 将套接字添加到键盘记录器

c++ - 在代码中定义字符串与控制台输入之间的区别