Sending a long String over a Socket C++

心已入冬 提交于 2019-12-25 07:42:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!