# Revision history [back]

ROS messages are transferred over TCP as serialized data.

If you're subscribing to normal message type (for example std_msgs/String or whatever), then ros::serialization::Serializer<std_msgs::String>::read() is called by roscpp to deserialize the message, and the deserialized message is passed to your callback.

If you're publishing to normal message type (for example std_msgs/String or whatever), then ros::serialization::Serializer<std_msgs::String>::write() is called after you call publish(), to serialize the message.

If you're publishing and subscribing std_msgs::String::ConstPtr within the same process (often when using nodelets), the serialization and deserialization steps are skipped for messages passed within the same process. (if there are publishers or subscribers outside the process, serialization still happens).

rosbag is a bit of a special case; instead of handling normal messages, it directly handles the serialized data and message description. When rosbag records, it writes the serialized data (and the message MD5) directly to the bag file, without deserialized it (and without needing to be compiled against every message type). When rosbag plays back a file, it advertises with the same MD5 that was used during recording, and then it reads the serialized data and publishes it directly. Deserialization of these messages happens in the subscriber in the normal way (assuming the MD5 still matches).

The rosbag instantiate() is only used in the rosbag C++ API, if you want to read a specific message type from a bag file in C++.