Skip to main content
U.S. flag

An official website of the United States government

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Connecting to NML from languages other than C++ or Java via sockets.

Connecting to NML from languages other than C++ or Java via sockets.
CAUTION! The Java NML Interface was changed since this document was written. Although the interface described here is still avialable and the examples are written in java. Java programmers should probably see NML Programmers Interface (Java Version).


Introduction

When using languages other than C++ with NML, there are several problems. The header files with the NML message definitions can not be included. The libraries for managing the NML communications are not available. In the case of a Java applet the NML configuration file might also not be available. One solution to this problem is to link together C++ code with the code written in another language into a single program. This was the approach used in the EMC Graphical User Interface which is primarily written in Visual Basic. Another approach is that the program written in non-C++ connect via sockets to an NML server. However because the NML server has many options writing the client might require a great deal of work to support all the options. Also, the default interface requires handling binary data which can more difficult to deal with than text, especially in scripting languages. Here I will choose a set of options that simplifies the interface for a Java client and describe how the client can be written.

NML Configuration

On each buffer line for buffers remove any of the following if they were there: (TCP=?, UDP=?, ascii, xdr). Then add "STCP=" to set the remote protocol to a simplified TC P protocol to the end of each buffer line. Unlike the normal TCP protocol, each buffer must have a unique port. Add "disp" to set the updater type to the ascii display type.

Java Socket Code

To open a connection create a new socket, making sure to match the host and port from the NML configuration file.

String host = "giskard.cme.nist.gov"; int port = 2001; Socket nmlsocket; nmlSocket = new Socket(host, port); 

Then create a DataInputStream and DataOutputStream using that socket.

DataOutputStream nmlOs; DataInputStream nmlIs; nmlOs = new DataOutputStream(nmlSocket.GetOutputStream); nmlIs = new DataInputStream(nmlSocket.GetInputStream); 

To read from an NML buffer, write "read:\n" or "peek:" to the DataOutputStream, then read a line from the DataInputStream. The line will contain the NML message beginning with the type and size of the message and followed by members in the order the update functions are called. (The size indicates the size of the structure in C++ not the length of the string returned. -- Ignore it.) The parameters are separated by commas. Below is an example of how to parse this string.

// Receive the current position. String nmlMsgString; long type; long size; float x; int index; nmlOs.writeBytes("read:\n"); nmlMsgString = nmlIs.ReadLine(); // nmlMsgString might look like this "8010,32,5.0,-25.0,0.7" type = (Long.valueOf(nmlMsgString)).longValue(); index = nmlMsgString.indexOf(","); size = (Long.valueOf(nmlMsgString.substring(index))).longValue(); index = nmlMsgString.indexOf(",",index); x = (Float.valueOf(nmlMsgString.substring(index))).floatValue(); 
To write to a NML buffer send write "write:" or "write_if_read:" followed by the message in the same form as they are read in, beginning with the type and size followed by members separated by commas. It is not necessary to provide all of the members of the message. Members omitted from the end of the string will be considered to be zero. It is also not necessary to calculate the size of the message, but a place holder is necessary if there are any other members to set in the string.
// Send the command to goto x,0,0 nmlOs.writeBytes("8001,0," + (new Double(x)).toString()); 

A Complete Example

This example consists of 3 programs:

  1. A C++ pseudo controller which accepts commands and updates a world model buffer. (wtimer.cc,timetype.cc, and timetype.hh)
  2. A C++ server which passes messages back and forth between remote processes and the local buffers read and updated by the controller.(timesvr.cc,timetype.cc, and timetype.hh)
  3. A Java Applet that sends commands when usa-buttons are pushed and polls the world model for display. (socapplet.java and CountButton.java)

The applet looks somewhat like a stopwatch. The controller doesn't have any hardware to control so I simulate world model by just updating the time in the world model buffer. Since we lack the computing resources here to run a separate controller for each user that starts the applet, pressing reset, start, or stop changes not only your display but also the display of anyone else viewing this applet.

NOTE:This applet that used to be here no longer works from this web page and has not worked for some time because of some security settings placed on this web server by our IT department.


Last Modified: 03/25/97

If you have questions or comments regarding this page or you would like to be notified of changes to the RCS library via email, please contact Will Shackleford at shackle [at] cme.nist.gov (shackle@c)

Created July 11, 2014, Updated June 2, 2021