套接字字符数组被追加

时间:2018-09-15 17:24:44

标签: c++ sockets

如图所示,

字符串变量和char变量 cout 不止一次。我有 ZeroMem()buff 我该如何对其进行归一化,以便引用“ Invader Said:RedditInvader Reddit”的“ Invader Said:Reddit”。

char buff[4096];
string serverMessage = "GET OUT MY SERVER!";

while (true) {
    ZeroMemory(buff, 4096);

    int bytesRecived = recv(clientSocket, buff, 4096, 0);

    if (bytesRecived == SOCKET_ERROR) {
        cerr << "Error in recv()! Qutting!" << endl;
    }

    if (bytesRecived == 0) {
        cout << "Client Disconnected" << endl;
        break;
    }

    cout << "Invader Said: " << buff;
    send(clientSocket, (char*)serverMessage.c_str(), serverMessage.length(), 0);
}

Problem Visualized

2 个答案:

答案 0 :(得分:1)

不能保证对方发送的所有字符都将在一条消息中发送。因此在PuTty端,当用户键入Reddit return 时,我们不完全知道所有这些数据将如何通过网络发送。

您的屏幕截图看起来与您的叙述有所不同,因为它们不是第二次Reddit:

Invader said: RedditInvader said: 

这是我基于此了解的内容。

在第一个循环中:

  • 您将一次收到6个字符
  • 没有错误,因此第一个if正文未执行
  • 没有空缓冲区,因此不会执行第二个if主体。
  • 您打印Invader said:,然后打印收到的字符Reddit
  • 您将第一封邮件发送回Putty

循环继续。在第二次迭代中:

  • 您将收到与 return 相同的内容(1或2个字符,在打印时看起来像换行符)
  • 没有错误,因此第一个if正文不会被执行
  • 没有空缓冲区,因此第二个if主体不被执行。
  • 您先打印Invader said:,然后打印收到的字符,看起来像换行符
  • 您再次向Putty发送一条消息

我无法告诉更多信息(断点?或recv()仍在等待,因为您没有 Ctrl + D ?...)

这是唯一的解释。如果您将一次收到所有PuTty字符,则会得到不同的输出:

Invader said: Reddit
Invader said:              (or something else, but on a new line)  

备注1:它与您的问题无关,但如果遇到错误,则程序将继续尝试打印输出和循环,因为在这种情况下您没有预见到break < / em>

注释2:它也没有链接,但是如果您一次收到正好为4096个字符,则输出可能会导致UB,因为缓冲区末尾会缺少空终止符

可能会让您感兴趣:

答案 1 :(得分:1)

您正在将buff视为终止为空的字符串,但是套接字数据并非终止为空。如果发生恰好接收4096个字节,则operator<<的使用将超出数组的范围。使用recv()时,必须考虑buff的返回值。

send()相同。它可能返回的字节数少于请求的字节数,因此您必须查看返回值,并可能不得不再次调用它以重新发送更多数据。

尝试以下方法:

char buff[4096];
const string serverMessage = "GET OUT MY SERVER!";
bool keepLooping = true;

while (keepLooping) {
    int bytesRecived = recv(clientSocket, buff, 4096, 0);
    if (bytesRecived == SOCKET_ERROR) {
        cerr << "Error in recv()! Qutting!" << endl;
        break;
    }

    if (bytesRecived == 0) {
        cout << "Client Disconnected" << endl;
        break;
    }

    cout << "Invader Said: ";
    cout.write(buff, bytesRecived);
    cout << endl;

    const char *ptr = serverMessage.c_str();
    size_t len = serverMessage.length();
    do {
        int bytesSent = send(clientSocket, ptr, len, 0);
        if (bytesSent == SOCKET_ERROR) {
            cerr << "Error in send()! Qutting!" << endl;
            keepLooping = false;
            break;
        }
        ptr += bytesSent;
        len -= bytesSent;
    }
    while (len > 0);
}