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

问题描述

我正在尝试使用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,'\0',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并发送硬编码整数之前放入一个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);