c++ - 通过套接字 C++ 发送长字符串

标签 c++ string sockets stringstream

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

服务器通过使用 ostringstream 对象和一些简单的换行符和空格格式将数据转储到一个长字符串中来打包包含播放器信息的结构数组,然后通过套接字将该字符串发送到显示给玩家的客户端。

当被打包的一个或多个结构中的“名称”字段超过 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 接收循环中,因为字符串在服务器端打印时会正确显示。我无法想象是什么导致了这样一个特定的错误,因为它只是发送了一个长字符串。

最佳答案

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 一次性发送或接收的消息。

关于c++ - 通过套接字 C++ 发送长字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37606349/

相关文章:

java - 有编辑程序流程的库吗?

c# - 格式加倍为百分比 - 显示所有小数?

ruby - 套接字不支持该操作- ruby 中的sendto(2)

linux - UNIX 套接字魔法。推荐用于高性能应用?

c++ - 使用 OpenCV C++ 检测和跟踪视频中液滴的步骤

c++ - 如果您有很多节点类型,则访问者模式

java - 如何在 main 中的所有声明对象中仅选择该数组中的随机元素一次?

string - 如何从随机位置的字符串部分获取不确定的数值?

c - 如何创建自己的数据包以通过 UDP 发送?

c++ - 自动生成基于成员的操作?