当字符串读取完成后,如何停止C ++ recv()?

时间:2016-06-30 15:47:30

标签: c++ sockets recv

我正在读取从Java客户端发送到Sockets的C ++服务器的图像URL。当检测到char缓冲区[]中有空字符时,服务器停止通过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] == '\0';
            i++;
        }

        if (finished)
            break;

    }
    while (bytes > 0);

    cout << message << endl;

    close(data->descriptor);
    pthread_exit(NULL);
}

是否有更好,更优雅的方式来做到这一点?

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

另一种方法可能是关闭Java套接字,以便recv()返回-1并且循环将完成。但是,考虑到我的Java客户端等待来自C ++服务器的响应,关闭套接字然后重新打开它似乎不合适。

谢谢你, 埃克托

1 个答案:

答案 0 :(得分:0)

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

我假设你的java客户端将发送一个空终止字符串然后等待,我。即特别是它不会发送任何进一步的数据。因此,在收到0字符之后,无论如何都不会有任何数据接收,所以不需要为recv隐式显式的事情而烦恼(recv通常只返回可用的数据,即使小于缓冲区可以消耗的。)

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

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