c++ - 我如何知道请求是否完全使用 TCP 套接字接收?

标签 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 字节。 所以,问题是:我需要知道请求是否被完全接收。 我正在考虑编写可能会告诉我是否收到完整请求的解析器​​,但我真的不知道如何检测完整请求。

最佳答案

I was thinking about writing parser that might tell me if a full request was received, but I don't really know how to detect full request.

在实现协议(protocol)时,建议实际仔细查看协议(protocol)的规范。

如果您阅读 HTTP 1.1 specification ,你会发现每个 HTTP message由标题和可选的正文组成。一旦您阅读了请求 header 和可选正文,该请求就被完整阅读了。 header 以空行 \r\n 序列结尾。某些 HTTP 方法,如 POST,可能有主体,在这种情况下,您将在 Content-Length header 中找到主体的长度,或者您必须处理与 chunked transfer encoding .

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

关于c++ - 我如何知道请求是否完全使用 TCP 套接字接收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50956504/

相关文章:

c++ - 如何在 Windows 中将套接字设置为阻塞模式?

sockets - accept() 和 TCP 数据包传递的行为

c++ - ifstream 无故失败?

c++ - 如何使用 std::array 模拟 C 数组初始化 "int arr[] = { e1, e2, e3, ... }"行为?

javascript - Ajax /套接字: javascript array object properties get lost

python - 是否有任何 python 库可以抽象基于 IP 的传输——TCP、UDP、SCTP、TLS 等?

java - 在java中将十六进制转换为ipv6格式

android - TCP 服务器接收数据的速度比发送数据的速度慢

c++ - C++ 协方差返回类型的缺点是什么?

c++ - 虚函数数组