【问题标题】:How to make a synchronous chat program to send and receive messages synchronously?如何制作一个同步聊天程序来同步发送和接收消息?
【发布时间】:2012-04-22 07:40:30
【问题描述】:

目前我正在用 C++ 创建一个客户端服务器控制台应用程序。使用winsock2.h库和UDP协议,我们使用sendtorecvfrom将消息作为字符串从客户端发送到服务器,然后服务器将消息发送到不同的客户端,如果客户端1发送向 client2 发送消息,client2 在尝试向 client1 发送消息之前不会收到该消息。我希望让程序像即时通讯工具一样工作,这样当客户端 1 向客户端 2 发送消息时,客户端 2 几乎会立即收到它,而无需先发送消息。

此外,如果客户端 1 向客户端 2 发送消息,客户端 1 将无法发送另一条消息,除非客户端 2 已回复第一个消息。

如果您需要更多信息或查看一些代码,请询问。

发送代码:

while( getline( cin, line ) )
{
    // send a string to the server.
    sendto( hSocket, line.c_str(), line.size(), 0, 
        reinterpret_cast<sockaddr*>( &serverAddress ),
        sizeof( serverAddress ) );

    // recieve the response.
    int n = recvfrom( hSocket, recvLine, MAXLINE, 0, NULL, NULL );
    if( n == -1 )
    {
        cout << "no reply" << endl;
    }
    else
    {
        recvLine[n] = 0;
        string const terminateMsg = "server exit";
        string msg = recvLine;
        if( msg == terminateMsg )
        {
            cout << "Server terminated" << endl;
            break;
        }
        cout << n << ": " << recvLine << endl;
    }
}

【问题讨论】:

  • Boost.ASIO。它甚至带有an example 用于这种确切的场景。
  • @ildjarn 谢谢你,他们的例子是我想要的,但我更愿意坚持使用 winsock 库
  • 那么你要做更多(非常丑陋)的工作。 ;-]
  • 你能发布一些代码,特别是 Socket 设置和发送的代码吗?我冒昧地猜测它实际上并没有将数据发送到网络堆栈,直到您尝试阅读,反之亦然。

标签: c++ udp client-server chat winsock


【解决方案1】:

现在如果client1向client2发送消息,client2不会 接收消息,直到他们尝试向 client1 发送消息。

你已经这样编码了。

另外,如果客户端 1 向客户端 2 发送消息,客户端 1 不会 能够发送另一条消息,除非客户端 2 已回复 第一个。

再一次,你是这样编码的。您的代码假定每个sendto() 后跟一个recvfrom()。但你的问题表明这不是你想要的。我在下面的代码中添加了一些 cmets

while( getline( cin, line ) )
{
    // send a string to the server. <-- will never get here a 2nd time through the loop without recvfrom() returning
    sendto( hSocket, line.c_str(), line.size(), 0, 
        reinterpret_cast<sockaddr*>( &serverAddress ),
        sizeof( serverAddress ) );

    // recieve the response. <--- will never get here without getline() returning
    int n = recvfrom( hSocket, recvLine, MAXLINE, 0, NULL, NULL );
    if( n == -1 )
    {
        cout << "no reply" << endl;
    }
    else
    {
        recvLine[n] = 0;
        string const terminateMsg = "server exit";
        string msg = recvLine;
        if( msg == terminateMsg )
        {
            cout << "Server terminated" << endl;
            break;
        }
        cout << n << ": " << recvLine << endl;
    }
}

我希望让程序像即时通讯工具一样工作,所以 当client1向client2发送消息时,client2会收到 几乎是即时的,无需先发送消息。

使用 Boost.Asio 和异步套接字,async chat_client example 使用 TCP 套接字完美地完成了这件事,修改 UDP 的示例相当简单。 async UDP echo server 示例也可能很有用。您需要使用boost::asio::ip::udp::socket::async_recv_from()boost::asio::ip::udp::socket::async_send_to()。其他 BSD 套接字接口具有在 documentation 中描述的等效映射。

【讨论】:

  • 谢谢,我会调查您在 cmets 中所说的内容,并尝试做出必要的更改,关于使用 boost,我更愿意坚持使用 winsock 库,但还是谢谢您跨度>
  • @Beef 使用 boost,它会让你的生活更轻松。没有理由重新发明轮子。 asio 库具有 BSD 套接字 API 的 显式 映射。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
相关资源
最近更新 更多