在Socket C ++上发送一个长字符串

时间:2016-06-03 05:10:12

标签: c++ string sockets stringstream

我遇到一些基本客户的奇怪问题< - >使用套接字的服务器通信。

服务器打包一个包含播放器信息的结构数组,方法是使用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(); 

屏幕截图,相关部分突出显示:

Screenshot with Error

Screenshot without Error

除非我遗漏了别的东西,否则99%肯定错误发生在客户端的do-while接收循环中,因为字符串在服务器端打印时显示正确。我不能因为我的爱想象会导致这样一个特定的错误,因为它只是一个长字符串被发送。

1 个答案:

答案 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一起发送或接收的消息。