How are messages exactly sent in bitcoin p2p protocol In order to send a NetMsgType::PING message to a node pnode, we simply invoke the function pnode-&gt;PushMessage(NetMsgType::PING) in src/main.cpp

This translates into following logic in src/net.h:

void PushMessage(const char* pszCommand)
{
    try
    {
        BeginMessage(pszCommand);
        EndMessage(pszCommand);
    }
    catch (...)
    {
        AbortMessage();
        throw;
    }
}


If we look carefully, the BeginMessage and EndMessage are just for acquiring and releasing the lock. Where exactly is the PING getting passed to the other node? I think the working is similar for other message types but the overloaded function PushMessage may use a Datastream which I guess does the passing to requested node. But I am particularly clueless about cases like NetMsgType::GETADDR, NetMsgType::VERACK and old version without nonce of NetMsgType::PING where there is only the command string pszCommand being passed
I got the answer myself. Sorry!

The src/net.cpp has this logic which explains all:

void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
{
    ENTER_CRITICAL_SECTION(cs_vSend);
    assert(ssSend.size() == 0);
    ssSend &lt;&lt; CMessageHeader(Params().MessageStart(), pszCommand, 0);
    LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}