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);
我正在尝试使用 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);