我遇到一些基本客户的奇怪问题< - >使用套接字的服务器通信。
服务器打包一个包含播放器信息的结构数组,方法是使用ostringstream
对象将数据转储到一个长字符串中,然后使用换行符和空格将一些简单的格式转换为,然后通过套接字将该字符串发送到客户端显示给玩家。
当打包的一个或多个结构中的“name”字段超过4个字符时,会出现问题;如果是这种情况,则包含5个以上字符的每个“名称”字段的第4个字符后面的每个字符都复制在字符串AFTER *发送到客户端的末尾的单行上。
*打包的字符串始终在服务器端正确显示。
下面是服务器和客户端的相关代码和两个截图,一个显示错误,另一个没有。
服务器代码:
struct leader_board_pos
{
string name;
int score;
};
leader_board_pos leader_board[num_players];
....
// Package and send the current leaderboard to the client
int i = 0;
string leader_board_package;
string dubspace = " ";
ostringstream oss;
cout << "Package leader board > "; cin.ignore();
leader_board_package = "Leader Board: \n";
while(i < num_leaders)
{
oss << leader_board[i].name << dubspace << leader_board[i].score << endl;
leader_board_package += oss.str();
oss.str(string());
i++;
}
cout << leader_board_package; cin.ignore();
bytes_sent = send(clientSock, leader_board_package.c_str(), leader_board_package.length(), 0);
if (bytes_sent != leader_board_package.length())
{
cout << "Server Message: Communication error..." << endl;
return;
}
客户代码:
const int MAX_BUFF_LENGTH = 4096;
...
//Get and display Leaderboard
int bytes_recv = 0;
vector<char> leader_board_buffer(MAX_BUFF_LENGTH);
string leader_board_package;
do {
bytes_recv = recv(sock, leader_board_buffer.data(), MAX_BUFF_LENGTH, 0);
if (bytes_recv == -1)
{
cout << "Communication error...";
return 0;
}
else
{
leader_board_package.append(leader_board_buffer.begin(), leader_board_buffer.end());
}
} while (bytes_recv == MAX_BUFF_LENGTH);
cout << endl << endl << leader_board_package; cin.ignore();
屏幕截图,相关部分突出显示:
除非我遗漏了别的东西,否则99%肯定错误发生在客户端的do-while接收循环中,因为字符串在服务器端打印时显示正确。我不能因为我的爱想象会导致这样一个特定的错误,因为它只是一个长字符串被发送。
答案 0 :(得分:1)
leader_board_package.append(leader_board_buffer.begin(), leader_board_buffer.end());
这是错误的。缓冲区仅包含bytes_recv
个接收数据。
while (bytes_recv == MAX_BUFF_LENGTH);
如果您从片段组装消息,则需要在某处将它们的长度相加。
此外,
if (bytes_sent != leader_board_package.length())
这也是错的。不要依赖send
能够立即发送整个阵列。正确的发送方式是以循环接收的方式进行循环。
目前还不清楚你的邮件大小应该是多少。如果它是变量,则需要使用消息进行传输。如果它是MAX_BUFF_LENGTH,则需要发送()这个确切的字节数。您不能依赖通过TCP一起发送或接收的消息。