0

String variable and char variable cout more than once as seen in the image. I have ZeroMem() buff How can I normalize it so it couts "Invader Said: Reddit" Instead of "Invader Said: RedditInvader 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 Answers2

1

There's no guarantee that the characters send by the other side will all be sent in one message. So on the PuTty side, when the user types Redditreturn we don't know exactly how all this data will be sent over the net.

Your screenshot looks different from your narrative becasue ther's no seccond Reddit:

Invader said: RedditInvader said: 

Here is what I understand based on it.

At the first loop:

  • You'll receive 6 chars at once
  • no error, so the first if body isn't executed
  • no empty buffer, so the second if body isn't executed.
  • You print Invader said:, followed by the chars received Reddit
  • You send back to Putty a first message

The loop continues. At the second iteration:

  • Your receive the equivalent of the return (1 or 2 chars that when printed out look like a newline)
  • no error, so the first if body isn't exectuted
  • no empty buffer, so the second if body isn't exectuted.
  • You print Invader said:, followed by the chars received, which look like a newline
  • You send back to Putty a second message

I can't tell more (breakpoint ? or recv() still waiting because you didn't Ctrl+D ? ...)

That's the only explanation. If you would have received all the PuTty chars at once, you would get a different output:

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

Remark 1: it's not linked to your problem, but if you encounter an error, your programme will keep trying to print output and looping, because you didn't foresee a break in this case

Remark 2: it's not linked either, but if you receive exactly 4096 chars at once, your output might cause UB, because there would be a missing null terminator at the end of the buffer

Could be of interest for you:

Christophe
  • 68,716
  • 7
  • 72
  • 138
1

You are treating buff as if it were a null terminated string, but socket data is not null terminated. If you happened to receive exactly 4096 bytes, your use of operator<< would exceed the bounds of the array. You must take the return value of recv() into account when using buff.

Same with send(). It may return fewer bytes than requested, so you have to look at the return value and potentially have to call it again to resend more data.

Try this instead:

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);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770