【问题标题】:Update data's clients in 1 server-n clients socket c++ mfc application在 1 个服务器和客户端套接字 c++ mfc 应用程序中更新数据客户端
【发布时间】:2020-06-14 14:45:40
【问题描述】:

我用 mfc 做了一个简单的检查登录程序。我使用 WSAAsyncselect 函数来创建一个非阻塞套接字。每次有人登录时,服务器都会向所有当前客户端发送一条消息“用户 x 已登录”,然后他们会在他们的消息日志中显示该消息。

通常,我只能在将数据发送到服务器后从调用 WSAAsyncselect 函数的按钮更新值。 例如

void CClientDlg::OnBnClickedLogin()
{
    // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    if ((m_username == "") || (m_password == ""))
    {
        return;
    }
    client = socket(AF_INET, SOCK_STREAM, 0);
    if (client == INVALID_SOCKET)
    {
        return;
    }
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PORT);
    char* IPstr = CT2A(IP);
    serverAddr.sin_addr.s_addr = inet_addr(IPstr);
    int error = connect(client, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if (error == SOCKET_ERROR) {
        return;
    }

    modestr = _T("1 ") + m_username + _T(",") + m_password;
    SendInfo(modestr);
    WSAAsyncSelect(client, m_hWnd, WM_SOCKET, FD_READ | FD_CLOSE);
    UpdateData(FALSE);
}

在服务器上,我有这个

BEGIN_MESSAGE_MAP(CServerDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_MESSAGE(WM_SOCKET, SockMsg)
END_MESSAGE_MAP()
LRESULT CServerDlg::SockMsg(WPARAM wParam, LPARAM lParam) {
    if (WSAGETSELECTERROR(lParam))
    {
        closesocket(wParam);
        MessageBox(_T("error"));
    }
    switch (WSAGETSELECTEVENT(lParam))
    {
    case FD_ACCEPT:
    {
        //accept client
        clientSocks.push_back(CLIENT(accept(wParam, NULL, NULL), "unidentified user"));

        break;
    }
    case FD_READ:
    {
        //check login codes
        //check login codes 
        //check login codes
                for (int i = 0; i < num_clients; i++) {
                    CString message = _T("0 ") + CString(user.c_str()) + _T("login\r\n");
                    SendResponse(clientSocks[i].clientSocket, message); //a send funtion to send data to 
                    //another socker
                }
}

服务器发送数据到这些客户端后,无论如何都会自动更新数据

【问题讨论】:

    标签: c++ sockets mfc wsaasyncselect


    【解决方案1】:

    不回答您的问题,因为此文本太长,无法发表评论。

    我认为您完全误解了WSAAsyncSelect 的工作原理。该函数打开基于 Windows 消息的从“客户端”到“服务器”的第二个通信通道。 (已经有一个通道:通过套接字的网络连接。)

    您使用WSAAsyncSelect 允许在后台进行数据传输,同时用户界面的消息循环可以继续运行并可以响应用户活动。

    nMsg 参数,在您的情况下为 WM_SOCKET,不会发送到不同的可执行文件,而是在请求的事件发生时发送到应用程序本身。这些告诉“嘿,我刚刚收到数据!”,“嘿,网络连接已关闭”,“嘿,现在有空间写入更多数据”。

    在您的示例中,当应用程序未读取数据时请求 FD_READ 事件是没有意义的。

    此外,由于您的“客户端”和“服务器”似乎都是用户界面应用程序,两者都应该使用WSAASyncSelect。发送端会监听FD_WRITE | FD_CLOSE事件(因为它必须写入数据),接收端会监听FD_READ | FD_CLOSE事件(因为它必须读取数据)。

    注意,一般情况下,使用WSAAsyncSelect的发送端实现起来非常复杂:它不仅仅是一个简单的write(),因为它必须准备好不是所有的数据可以一次发送。相反,它必须保留要发送的数据,必须记录已发送的数据和尚未发送的数据。因此,当数据包很小(最多几百字节)且不频繁时,我不会在发送方使用异步通信,并且只希望操作系统中的网络层能够为我缓存数据并且不会阻止write() 呼叫。

    【讨论】:

      猜你喜欢
      • 2019-03-17
      • 2023-03-18
      • 2017-05-26
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      相关资源
      最近更新 更多