c++charactersendreceiver

winsock printing too much


I wanted to try a server/client connection kind of thing, and so I modified the code from a YouTube tutorial (New to C++). So far everything works just fine, except when I try to print the message that was sent by the client.

The code used for sending and receiving data is the following:

char buf[4096];

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

    int bytesReceived = recv(clientSocket, buf, 4096, 0);
    if (bytesReceived == SOCKET_ERROR)
    {
        cerr << "Error in recv()! Quitting" << endl;
        break;
    }

    if (bytesReceived == 0)
    {
        cout << "Client disconnected!" << endl;
        break;
    }

    cout << buf << endl;
    send(clientSocket, buf, bytesReceived + 1, 0);
}

Sending it back works fine, as well a printing it to the console. However, in the console it prints a crazy amount of new lines after the initial output. I guess it has something to do with the size of the buf, which is 4096, but I don't know how to fix it.


Solution

  • recv() tells you how many bytes were actually put into your buf, but you are ignoring that value when printing the contents of buf. The operator<< you are using expects a null-terminated string, but recv() does not guarantee your buf is null-terminated (even if the client sends a null terminator, it may not have arrived yet when recv() exits).

    Use write() instead of operator<< when printing buf to std::cout, so that you can specify bytesReceived as the size to print.

    You are also sending 1 more byte back to the client then you actually received. You should not be adding +1 to bytesReceived when calling send().

    You also need to take into account that send() may accept fewer bytes for transmission than you ask for, so it needs to be called in a loop, just like with recv().

    Try this instead:

    char buf[4096], *ptr;
    int bytesReceived, bytesSent, errCode;
    
    while (true)
    {
        bytesReceived = recv(clientSocket, buf, sizeof(buf), 0);
        if (bytesReceived == SOCKET_ERROR)
        {
            errCode = WSAGetLastError();
            cerr << "Error " << errCode << " in recv()! Quitting" << endl;
            break;
        }
    
        if (bytesReceived == 0)
        {
            cout << "Client disconnected!" << endl;
            break;
        }
    
        cout.write(buf, bytesReceived);
        //cout << endl;
    
        ptr = buf;
        while (bytesReceived > 0)
        {
            bytesSent = send(clientSocket, ptr, bytesReceived, 0);
            if (bytesSent == SOCKET_ERROR)
            {
                errCode = WSAGetLastError();
                cerr << "Error " << errCode << " in send()! Quitting" << endl;
                break;
            }
            ptr += byteSent;
            bytesReceived -= byteSent;
       }
    
       if (bytesReceived > 0)
           break;
    }