我怎么知道是否使用TCP套接字完全收到了请求?

时间:2018-06-20 20:25:00

标签: c++ sockets tcp tcpserver

我有一个多线程HTTP TCP服务器(用Linux编写),下面是处理客户端的函数:

    void tcp_server::connection_handler(client* cl) {
    // add client to the clients <vector>
    mx.lock();

    cl->set_id(static_cast<int>(clients.size()));
    clients.push_back(*cl);
    cout << "New client with id " << cl->get_id() << " has been added to the clients list" << endl << endl;

    mx.unlock();

    char read_buffer[1024];
    ssize_t message_size;
    string received_message;
    while (accept_connections) {
        memset(&read_buffer, 0, sizeof(read_buffer));
        received_message.clear();

        message_size = recv(cl->sock, read_buffer, sizeof(read_buffer) - 1, 0);

        if (message_size == 0) {
            // client disconnected
            cout << "Client with id " << cl->get_id() << " has been disconnected" << endl;
            close(cl->sock);

            //remove client from the clients <vector>
            mx.lock();

            int client_index = find_client_index(cl);
            clients.erase(clients.begin() + client_index);
            cout << "Client with id " << cl->get_id() << " has been removed from the clients list" << endl;

            mx.unlock();

            delete cl;

            break;
        }
        if (message_size == -1) {
            if (!accept_connections) {
                cerr << "Unable to receive message from client with id " << cl->get_id() << ". Server has been shut down. Stop receiving messages from this client" << endl;
            }
            else {
                cerr << "Error while receiving message from client with id " << cl->get_id() << endl;
            }
            cerr << strerror(errno) << endl;
        }
        else {
            //message was received succesfully

            cout << "[Server] Client's message has been received" << endl;
            cout << "[Server] Client's message: " << endl;
            cout << "----------------------------" << endl;
            cout << read_buffer << endl;
            cout << "----------------------------" << endl;

            for (unsigned int i = 0; i < message_size; i++) {
                received_message.push_back(read_buffer[i]);
            }

            string response_message = convert_client_message(received_message);

            if (send(cl->sock, response_message.c_str(), response_message.size(), 0) == -1) {
                cout << "[Server] Message sending to client with id " << cl->get_id() << " failed" << endl;
            }

            cout << "[Server] Server's response: " << endl;
            cout << "----------------------------" << endl;
            cout << response_message << endl;
            cout << "----------------------------" << endl << endl;

            cout << "[Server] Message has been sent to client" << endl << endl;
            cout << "============================" << endl << endl;
        }
    }
}

您怎么看,有一个缓冲区,其中包含客户的消息,只有1024字节,而请求可以大于1024字节。 因此,问题是:我需要知道请求是否已完全收到。 我当时正在考虑编写解析器,该解析器可能会告诉我是否收到了完整请求,但是我真的不知道如何检测完整请求。

1 个答案:

答案 0 :(得分:4)

  

我当时正在考虑编写解析器,该解析器可以告诉我是否收到了完整的请求,但是我真的不知道如何检测完整的请求。

实施协议时,建议您仔细查看协议规范。

如果您阅读HTTP 1.1 specification,您将意识到每个HTTP message包含标题和可选的正文。阅读请求标头和可选主体后,请求将被完全读取。 标题以空行\r\n序列结束。某些HTTP方法(例如POST)可能具有主体,在这种情况下,您将在Content-Length标头中找到主体的长度,或者必须处理chunked transfer encoding

请研究规格以获取更多详细信息。