Satoshi Client Operation: Sockets and Messages
The original bitcoin client uses a multithreaded approach to socket
handling and messages processing. There is one thread that handles
socket communication (ThreadSocketHandler) and one (ThreadMessageHandler)
which handles pulling messages off sockets and calling the
processing routines. Both of these threads are in net.cpp.
The message processing routines are in main.cpp, however.
The socket thread reads the sockets and places data into a CDataStream
associated with each node called vRecv. The Satoshi client uses C++
serialization operators >> and << to read and write to a CDataStream
and then it uses generic routines to move the data between the streams
The message thread reads and processes all messages from each node in
sequence, and then it sends messages to each node that should be sent
messages. That is all it does.
Specifically, ThreadSocketHandler2 calls ProcessMessages(), which is
located in main.cpp, to pull messages off each node's socket and
process them. Then it calls SendMessages(), which is also located
in main.cpp to create and send any messages appropriate for each node.
ProcessMessages() attempts to find a message start signature in the
vRecv stream. If it finds a message start, it deletes everything
prior to the start. Then it reads the header, extracts the message
type, and calls ProcessMessage on the message.
SendMessages() actually creates and sends messages; it does not
just send preexisting queued messages. It goes through various
maps looking for work to do and produces a message and calls
PushMessage method of CNode to send the message. PushMessage
queues outbound data in the vSend data stream. (See PushMessage() in
net.cpp). The socket thread handler then pulls data off the
vSend data stream and calls send on the socket to send the data.
Search on "Satoshi Client Operation" for more articles in this series.