问题
I'm having a strange issue with some basic client <-> server communication using sockets.
The server packages an array of structs containing player information by dumping the data into one long string using an ostringstream
object and some some simple formatting with newlines and spaces, then sends that string via socket to the client to be displayed to the player.
The issue arises when the "name" field in the one or more of the structs being packaged is longer than 4 characters; if this is the case every character after the 4th from each "name" field containing 5+ characters is duplicated on a single line at the end of the string AFTER* being sent to the client.
*The packaged string always displays properly on the server side.
Below is the relevant code and two screenshots of server and client terminal, one displaying the error, the other without.
SERVER CODE:
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;
}
CLIENT CODE:
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();
The Screenshots, Relevant sections highlighted:
Screenshot with Error
Screenshot without Error
Unless I'm missing something else I'm 99% sure the error is in the do-while receive loop on the client-side since the string displays appropriately when printed on the server-side. I can't for the love of me imagine what would cause such a specific error since it's just one long string being sent.
回答1:
leader_board_package.append(leader_board_buffer.begin(), leader_board_buffer.end());
This is wrong. The buffer only contains bytes_recv
worth of received data.
while (bytes_recv == MAX_BUFF_LENGTH);
If you assemble the message from pieces, you need to add their lengths together somewhere.
In addition,
if (bytes_sent != leader_board_package.length())
This is wrong too. Don't rely on send
being able to send the entire array at once. The right way to send is to loop much in the same way you loop receiving.
It is also unclear what's the size of your message is supposed to be. If it's variable, you need to transmit it with the message. If it's MAX_BUFF_LENGTH, you need to send() this exact number of bytes. You cannot rely on a message being sent or received in one piece over TCP.
来源:https://stackoverflow.com/questions/37606349/sending-a-long-string-over-a-socket-c