pointers – Differentiating between two values sent over WinSock (C++)


(crossposted from Stack Overflow)

I have a C++ Server and Client running locally, they are connected through WinSock and can communicate.

I need to send two distinct kinds of updates between them (updateA & updateB).

updateA is a char* but updateB is an object pointer. I can not access the object that updateB points to (though I know that it is some form of string/char – all I know is its length).

Currently, I send both of these variables between Server and Client the same way, but they can be sent in any order depending on circumstances:

iResult = send( this->ClientSocket, (char*)this->updateA, this->updateALength, 0 );
//check for errors etc
iResult = send( this->ClientSocket, (char*)this->*updateB, this->updateBLength, 0 );
//check for errors etc

But on arrival they need to be handled differently, eg:

int iResult = recv( this->ConnectSocket, recvbuf, recvbuflen, 0 );
if( iResult > 0 )
{
    if(is_updateA(recvbuf))
    {
        //do updateA things
    } elif (is_updateB(recvbuf)) {
        //do updateB things
    }
}

According to typeid( recvbuf ).name() both updates are of the type char (1024) (both cast to char* during the send as prior to that updateA is a char const * __ptr64 and updateB is a unsigned char * __ptr64).

What would be the cleanest way to differentiate between updateA and updateB? I’ve considered appending some kind of tag onto the beginning of updateA but this does not feel like a very robust solution.

Full code.
Server

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "6000"

bool Server::checkSendResult( int iResult, const char* command )
{
    if( iResult == SOCKET_ERROR )
    {
        printf( "n", command, " failed with error: %dn", WSAGetLastError() );
        closesocket( this->ClientSocket );
        WSACleanup();
        return false;
    }
    return true;
}

int main(){
WSADATA wsaData;
    int iResult;

    this->ListenSocket = INVALID_SOCKET;
    this->ClientSocket = INVALID_SOCKET;

    struct addrinfo* result = NULL;
    struct addrinfo hints;

    // Initialize Winsock
    printf( "Initializing Winsock...n" );
    iResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
    if( iResult != 0 )
    {
        printf( "WSAStartup failed with error: %dn", iResult );
        return 1;
    }

    printf( "Initializing hints...n" );
    ZeroMemory( &hints, sizeof( hints ) );
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the server address and port
    printf( "Resolving server address and port...n" );
    iResult = getaddrinfo( NULL, DEFAULT_PORT, &hints, &result );
    if( iResult != 0 )
    {
        printf( "getaddrinfo failed with error: %dn", iResult );
        WSACleanup();
        return false;
    }

    // Create a SOCKET for connecting to server
    printf( "Creating a socket...n" );
    this->ListenSocket = socket( result->ai_family, result->ai_socktype, result->ai_protocol );
    if( this->ListenSocket == INVALID_SOCKET )
    {
        printf( "socket failed with error: %ldn", WSAGetLastError() );
        freeaddrinfo( result );
        WSACleanup();
        return false;
    }

    // Setup the TCP listening socket
    printf( "Setting up listening socket...n" );
    iResult = bind( this->ListenSocket, result->ai_addr, (int)result->ai_addrlen );
    if( !this->checkSendResult( iResult, "Bind" ) )
    {
        freeaddrinfo( result );
        return false;
    }

    freeaddrinfo( result );

    printf( "Listening to listen socket...n" );
    iResult = listen( this->ListenSocket, SOMAXCONN );
    if( !this->checkSendResult( iResult, "Listen" ) ){ return false; }

    // Accept a client socket
    printf( "Accepting a client...n" );
    this->ClientSocket = accept( this->ListenSocket, NULL, NULL );
    if( this->ClientSocket == INVALID_SOCKET )
    {
        printf( "accept failed with error: %dn", WSAGetLastError() );
        closesocket( this->ListenSocket );
        WSACleanup();
        return false;
    }
    printf( "Done setting up server!n" );
    int iResult;
    int iSendResult;

    int iResult = recv( this->ClientSocket, recvbuf, recvbuflen, 0 );
    if( iResult > 0 )
    {
        if(is_updateA(recvbuf)) // function TBD
        {
             printf("It was Update A!n");
        } elif (is_updateB(recvbuf)) //function TBD
             printf("It was Update B!n");
        }
    }

    std::string result = "(updateA) A new message for youn"; // could be updateB instead
    iSendResult = send( this->ClientSocket, result.c_str(), (int)strlen( 
    result.c_str() ), 0 );
    if( !this->checkSendResult( iResult ) ){ return false; }
}

Client

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define DEFAULT_BUFLEN 1024
#define DEFAULT_PORT "6000"



int main(){

int iResult;
int iSendResult;

WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    const char* sendbuf = "this is a test";
    int iResult;


    // Initialize Winsock
    iResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
    if( iResult != 0 )
    {
        printf( "WSAStartup failed with error: %dn", iResult );
        return 1;
    }

    ZeroMemory( &hints, sizeof( hints ) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo( "127.0.0.1", DEFAULT_PORT, &hints, &result );
    if( iResult != 0 )
    {
        printf( "getaddrinfo failed with error: %dn", iResult );
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for( ptr = result; ptr != NULL; ptr = ptr->ai_next )
    {

        // Create a SOCKET for connecting to server
        this->ConnectSocket = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol );
        if( this->ConnectSocket == INVALID_SOCKET )
        {
            printf( "socket failed with error: %ldn", WSAGetLastError() );
            WSACleanup();
            return 1;
        }

        // Connect to server.
        iResult = connect( this->ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen );
        if( iResult == SOCKET_ERROR )
        {
            closesocket( this->ConnectSocket );
            this->ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo( result );

    if( this->ConnectSocket == INVALID_SOCKET )
    {
        printf( "Unable to connect to server!n" );
        WSACleanup();
        return 1;
    }
do
    {

        iResult = recv( this->ConnectSocket, recvbuf, recvbuflen, 0 );
        if( iResult > 0 )
        {
            printf( "nMessage received: %sn", recvbuf );
            if(is_updateA(recvbuf)) // function TBD
            {
                 printf("It was Update A!n");
            } elif (is_updateB(recvbuf)) //function TBD
                 printf("It was Update B!n");
            }

        }
        else if( iResult == 0 )
        {
            printf( "nConnection closedn" );
        }
        else
        {
            printf( "nrecv failed with error: %dn", WSAGetLastError() );
        }
        printf( "nEAC client logs while closing:n%sn", this->eacClient.getOutput().c_str() );
        this->eacClient.resetOutput();
    } while( iResult > 0 );

    // cleanup
    closesocket( this->ConnectSocket );
    WSACleanup();
}

```