VRPN 06.04

VRPN main page

Obtaining VRPN

VRPN Support

Installing and Testing

Compiling and Modifying

Client code

Server code

Troubleshooting

Connections

Logging and Playback

Shared Objects

Sound

Clock Synchronization

Text Messages

Doxygen documentation

VRPN on PDAs

Coming attractions & suggestions

UNC-specific information

Sending a message

Once the sender and type of a message have been described, it is possible to begin sending messages over a connection. Messages are given to a connection using the pack_message() method:

	virtual int pack_message(int len, struct timeval time,
				 long type, long sender, char *buffer,
				 unsigned long class_of_service);

The len parameter specified the length of the message, in bytes. In order to maintain alignment, the connection will internally pad this length to a multiple of 8 characters. The padding will be removed when the message is delivered. The connection will guarantee that messages begin on an 8-byte boundary when delivered.

The time parameter is the time at which the message was generated, according to the local clock on the machine generating the message. This need not be the time that the message was queued; for example, some tracker drivers put the time that the first character was received from a serial port for a tracker record.

The type and sender parameters are the tokens received when they were registered.

The buffer parameter points to the data that is to be sent, in architecture-independent byte order. This allows messages to be sent between hosts that differ in byte order. Use the vrpn_buffer() and vrpn_unbuffer() functions defined in vrpn_Shared.h to make sure that the byte ordering matches the network standard. In fact the buffer is delivered byte-for-byte to the receiver at the other end of a connection link, so any format is legal so long as the sender and receiver agree on what it will be. For example, a device might be implemented that used receiver-makes-it-right byte ordering by checking the order of a token long at the beginning of the message and swapping all values only if needed. All VRPN system devices use common-format, agreeing with the htonl() standard.

The class_of_service parameter describes the type of delivery required for this message. These classes are listed at the top of the vrpn_Connection.h file. This parameter is a bitwise OR of the flags. In the current implementation, all flags except vrpn_CONNECTION_RELIABLE are ignored; if this flag is set, the TCP channel is used for delivery; otherwise, UDP is used.

Important notes

For network connections, messages are not sent until the mainloop() method is called. There are separate buffers for UDP and TCP delivery; both are sent when mainloop() is called. In a possible future implementation of shared-memory or single-thread implementation, the messages may be delivered as soon as they are packed, so code using this should allow for delivery (and callback invocation) any time from when the message is queued until the next time mainloop() is called.

If a callback has been specified for the given sender and type on the connection object to which a message is packed, that message will be delivered locally as well as being sent across the connection.

For listening connections that do not currently have a link to a remote connection, messages that are packed will not be delivered, but will be silently discarded when mainloop() is called. Messages will still be sent to any local callback that has been specified.

Example

The following code will open a connection, describe a sender and type, and send a message reliably on the connection. This is a contrived example because there will almost certainly be nobody listening when the message is sent:

	vrpn_Connection *connection = new vrpn_Connection();
	long my_type = connection->register_message_type("Test_type");
	long my_id = connection->register_sender("Test0@ioglab.cs.unc.edu");

	struct timeval now;
	gettimeofday(&now,NULL);

	connection->pack_message(sizeof("Hi!"), now, my_type, my_id,
				 "Hi!", vrpn_CONNECTION_RELIABLE);
	connection->mainloop();