TCP/IP 套接字接收随机大数

TCP/IP socket receives random big number

我正在尝试使用 TCP/IP 套接字在 C++ 中创建一个客户端-服务器应用程序,但是当我尝试从服务器接收数据时,客户端会收到一个随机的大数字,即使服务器没有'不发送。

在服务器端,我首先接收客户端的用户,然后发送服务器的名称和用户的角色:

std::string user = Communication_Protocol::recv_message(client_sock, logger);
client.set_user(user);

int user_role = database_manager.get_user_role(user);

Communication_Protocol::send_message(client_sock, this->name, logger);
Communication_Protocol::send_message(client_sock, std::to_string(user_role), logger);

在客户端,我首先发送用户,然后收到服务器的名称和用户的角色:

Communication_Protocol::send_message(client_sock, username, logger);
server_name = Communication_Protocol::recv_message(client_sock, logger);
role = std::stoi(Communication_Protocol::recv_message(client_sock, logger));
logger->add("ROLE=" + std::to_string(role));

从通信协议中使用的函数是:

    void send_message(SOCKET socket, std::string message, Logger *logger){
        std::string encapsulated_string = message;
        size_t total_bytes_sent = 0;
        size_t bytes_sent = 0;
        size_t size = encapsulated_string.size();
        send(socket, &size, sizeof(size), 0);
        while (total_bytes_sent < encapsulated_string.size()){
            std::string message_left = encapsulated_string.substr(bytes_sent);
            bytes_sent = send(socket, message_left.c_str(), sizeof(message_left.c_str()), 0);
            total_bytes_sent += bytes_sent;
            logger->add_network("SEND", encapsulated_string.substr(total_bytes_sent - bytes_sent, total_bytes_sent), "<RECIVER>");
            if(bytes_sent < 0){
                logger->add_error("MESSAGE NOT SENT");
                return;
            }
        }
                            
    }
    std::string get_message(SOCKET socket, size_t size){
        std::string message = "";
        char *recv_buffer = new char[BUFFER_SIZE];
        size_t bytes_recived = 0;
        while (bytes_recived < size){
            memset(recv_buffer, '[=13=]', BUFFER_SIZE);
            size_t len = recv(socket, recv_buffer, size - bytes_recived, 0);
            if(len < 0){
                throw Socket_Error_Exception();
            }
            if(len == 0){
                throw Client_Down_Exception();
            }
            std::string recv_msg = std::string(recv_buffer); 
            message += recv_msg;
            bytes_recived += len;
        }
        delete recv_buffer;
        return message;        
    }
    std::string recv_message(SOCKET socket, Logger *logger){
        long message_size;
        std::string message = "";
        size_t recv_len = recv(socket, &message_size, sizeof(message_size), 0);
        if(message_size > 0){
            logger->add_network("RECV", "SIZE = " + std::to_string(message_size), "<SENDER>");
            message = get_message(socket, message_size);
            logger->add_network("RECV", "BODY = " + message, "<SENDER>");
        }
        
        return message;
    }

服务器日志:

2020-8-16 16:51:45  NET RECV SIZE = 4 FROM <SENDER>
2020-8-16 16:51:45  NET RECV BODY = USER FROM <SENDER>
2020-8-16 16:51:45  NET SEND xxx TO <RECIVER>
2020-8-16 16:51:45  NET SEND -1 TO <RECIVER>

客户端日志:

2020-8-16 16:51:45  NET SEND USER TO <RECIVER>
2020-8-16 16:51:45  NET RECV SIZE = 3 FROM <SENDER>
2020-8-16 16:51:45  NET RECV BODY = xxx FROM <SENDER>
2020-8-16 16:51:45  NET RECV SIZE = 2199031643136 FROM <SENDER>

我试过更改消息的顺序,但只有来自服务器的第一条消息被正常接收,第二条消息的大小很大。
我认为这是字符串中缺少“\0”或溢出,但我看不到此类错误的来源。
我还认为问题出在从数据库接收用户的角色,但我试图在接收它之前放置一个 sleep_for 并发送一个硬编码整数,但我遇到了同样的问题。

send_message 内,您使用 sizeof(message_left.c_str()) 作为消息长度。那是指针的大小。你可能想要 message_left.size() 而不是:

bytes_sent = send(socket, message_left.c_str(), message_left.size(), 0);

recv_message 中,您正在使用 message_size,您可能想在其中使用返回的 recv_len - recv_len 也应该是 ssize_t,因为它可以是 -1:

    ssize_t recv_len = recv(socket, &message_size, sizeof(message_size), 0);
    if (recv_len > 0){

get_message内,len也应该是ssize_t:

ssize_t len = recv(socket, recv_buffer, size - bytes_recived, 0);