如何在字符串读取完成时停止c++的recv() ?

How can I stop C++ recv() when string read is finished?

本文关键字:c++ recv 字符串 读取 完成时      更新时间:2023-10-16

我正在阅读从Java客户端发送到c++服务器从套接字的图像URL。当服务器检测到字符缓冲区[]中有一个空字符时,它会停止读取recv(),正如我在下面的代码中所做的那样:

void * SocketServer::clientController(void *obj)
{
    // Retrieve client connection information
    dataSocket *data = (dataSocket*) obj;
    // Receive data from a client step by step and append data in String message
    string message;
    int bytes = 0;
    do
    {
        char buffer[12] = {0};
        bytes = recv(data->descriptor, buffer, 12, 0);
        if (bytes > 0) // Build message
        {
            message.append(buffer, bytes);
            cout << "Message: " << message << endl;
        }
        else // Error when receiving it
            cout << "Error receiving image URL" << endl;

        // Check if we are finished reading the image link
        unsigned int i = 0;
        bool finished = false;
        while (i < sizeof(buffer) / sizeof(buffer[0]) && !finished)
        {
            finished = buffer[i] == '';
            i++;
        }
        if (finished)
            break;
    }
    while (bytes > 0);
    cout << message << endl;
    close(data->descriptor);
    pthread_exit(NULL);
}

是否有更好更优雅的方法来做这个?

我读到关于首先发送URL的大小,但我不知道如何用它停止recv()。我猜这是通过计算收到的字节数来完成的,直到达到URL的大小。在那一刻,我们应该完成阅读。

另一种方法是关闭Java套接字,这样recv()将返回-1,循环将结束。然而,考虑到我的Java客户端等待来自c++服务器的响应,关闭套接字然后重新打开它似乎不是一个合适的选择。

谢谢你,赫克托耳

除了你的缓冲区有一个不寻常的大小(通常选择2的幂,所以8,16,32,…),它看起来有点小你的意图,你的方法对我来说似乎很好:

我假设您的java客户端将发送一个以空结尾的字符串,然后等待,即特别是它不发送任何进一步的数据。因此,在您接收到0字符之后,无论如何都不会再接收任何数据,因此不需要为recv隐式执行的显式操作费心(recv通常只返回可用的数据,即使少于缓冲区可以消耗的数据)。

请注意,您使用0初始化缓冲区,因此如果您检查整个缓冲区(而不是范围[buffer, buffer + bytes]),您可能会检测到假阳性(如果您在第一次迭代中收到少于12个字符)!不过,检测0字符可以更优雅地完成:

if(std::find(buffer, buffer + bytes, 0) < buffer + bytes)
{
    // found the 0 character!
    break;
}