static void Main(string[] args)
        {
            Dictionary <string, dynamic> dict;
            int i;

            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<master_ip> <slave_ip>] <output_file>] <samples_to_receive]
            string master_ip   = MASTER_IP;
            string slave_ip    = SLAVE_IP;
            string output_file = OUTPUT_FILE;

            if (args.Length >= 2)
            {
                master_ip = args[0];
                slave_ip  = args[1];
            }
            if (args.Length >= 3)
            {
                output_file = args[2];
            }
            if (args.Length >= 4)
            {
                samples_to_receive = Convert.ToInt32(args[3]);
            }

            // Instantiate Socket array.
            sock = new Socket[NumberOfModules];

            // Initialize boundary objects
            LanXIRESTBoundary master = new LanXIRESTBoundary(master_ip);
            LanXIRESTBoundary slave  = new LanXIRESTBoundary(slave_ip);

            SetRecorderStateTo(master, "Idle");
            SetRecorderStateTo(slave, "Idle");

            // Start measurement
            // During this process commands are generally performed on SLAVEs first, finished with MASTER

            // Set synchronization mode on the LAN-XI modules. The body tells which module is master and which is slave. Body for each module is prepared in SyncParametersMaster.json and SyncParametersSlave.json
            // For this command, the MASTER should be treated first, then the slave(s)
            string syncParametersMaster = File.ReadAllText(@"CIC_SyncParametersMaster.json");

            master.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster);
            string syncParametersSlave = File.ReadAllText(@"CIC_SyncParametersSlave.json");

            slave.PutRequestWithPath("/rest/rec/syncmode", syncParametersSlave);

            // Wait until PTP is locked on all modules
            slave.WaitForPtpState("Locked");
            master.WaitForPtpState("Locked");

            // Open the Recorder application on the modules. The same body is sent to both modules, and is prepared in OpenParameters.json
            string openParameters = File.ReadAllText(@"CIC_OpenParameters.json");

            slave.PutRequestWithPath("/rest/rec/open", openParameters);
            master.PutRequestWithPath("/rest/rec/open", openParameters);

            /*
             * // Prepare generator
             * string outputChannelStart = File.ReadAllText(@"CIC_OutputChannelStart.json");
             * slave.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);
             *
             * // Configure generator channels
             * string outputChannelConfiguration = File.ReadAllText(@"CIC_OutputChannelSetup.json");
             * slave.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);
             *
             * // Start output
             * slave.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
             * master.PutRequestWithPath("/rest/rec/apply", null);
             *
             */


            // Wait for all modules to be ready; Input in Sampling state, and module in the RecorderOpened state.
            slave.WaitForInputState("Sampling");
            master.WaitForInputState("Sampling");
            slave.WaitForRecorderState("RecorderOpened");
            master.WaitForRecorderState("RecorderOpened");

            // Create Recorder configuration on all modules
            slave.PutRequestWithPath("/rest/rec/create", null);
            master.PutRequestWithPath("/rest/rec/create", null);

            // Wait for all modules to be in the RecorderConfiguring state.
            slave.WaitForRecorderState("RecorderConfiguring");
            master.WaitForRecorderState("RecorderConfiguring");

            string CicConfig = File.ReadAllText(@"Cic_Configuration.json");

            slave.PutRequestWithPath("/rest/rec/channels/cic", CicConfig);


            // The body has been prepared and stored in CIC_MasterInputChannelSetup.json.
            string MasterInputChannelConfiguration = File.ReadAllText(@"CIC_MasterInputChannelSetup.json");
            string SlaveInputChannelConfiguration  = File.ReadAllText(@"CIC_SlaveInputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/channels/input", SlaveInputChannelConfiguration);
            master.PutRequestWithPath("/rest/rec/channels/input", MasterInputChannelConfiguration);

            // Wait until all modules enter the Settled input state
            slave.WaitForInputState("Settled");
            master.WaitForInputState("Settled");

            // Synchronize modules.
            slave.PutRequestWithPath("/rest/rec/synchronize", null);
            master.PutRequestWithPath("/rest/rec/synchronize", null);

            // Wait for all modules to enter the Synchronized input state
            slave.WaitForInputState("Synchronized");
            master.WaitForInputState("Synchronized");

            // Start streaming between internally in the LAN-XI modules.
            slave.PutRequestWithPath("/rest/rec/startstreaming", null);
            master.PutRequestWithPath("/rest/rec/startstreaming", null);

            // Wait for all modules to enter the RecorderStreaming state
            slave.WaitForRecorderState("RecorderStreaming");
            master.WaitForRecorderState("RecorderStreaming");

            // Get the TCP ports provided by each LAN-XI module for streaming samples
            dict = master.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 slavePort = (UInt16)dict["tcpPort"];

            dict = slave.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 masterPort = (UInt16)dict["tcpPort"];

            // Connect to sockets. Let ConnectStreams() handle this.
            ConnectStreams(new string[] { master_ip, slave_ip }, new UInt16[] { masterPort, slavePort });

            // Start measuring.
            slave.PostRequestWithPath("/rest/rec/measurements", null);
            master.PostRequestWithPath("/rest/rec/measurements", null);

            // Wait for modules to enter RecorderRecording state
            slave.WaitForRecorderState("RecorderRecording");
            master.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running.

            // Let Stream() method handle streaming
            Stream();

            // Stop measuring and close sockets for all modules.
            // During this process commands are generaly performed on MASTER module first, then on SLAVEs

            // Stop measurement on modules
            master.PutRequestWithPath("/rest/rec/measurements/stop", null);
            slave.PutRequestWithPath("/rest/rec/measurements/stop", null);

            // Wait for all modules to enter RecorderStreaming state
            master.WaitForRecorderState("RecorderStreaming");
            slave.WaitForRecorderState("RecorderStreaming");


            // Close sockets
            for (i = 0; i < NumberOfModules; i++)
            {
                sock[i].Shutdown(SocketShutdown.Both);
                sock[i].Close();
            }

            // Finish recording
            master.PutRequestWithPath("/rest/rec/finish", null);
            slave.PutRequestWithPath("/rest/rec/finish", null);

            // Stop output
            //            master.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);
            //            slave.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            // Wait for modules to enter the RecorderOpened state
            master.WaitForRecorderState("RecorderOpened");
            slave.WaitForRecorderState("RecorderOpened");

            // Close Recorder application on all modules
            master.PutRequestWithPath("/rest/rec/close", null);
            slave.PutRequestWithPath("/rest/rec/close", null);

            // Wait for modules to enter the Idle state
            master.WaitForRecorderState("Idle");
            slave.WaitForRecorderState("Idle");

            // Write collected samples to output file
            StreamWriter file = new StreamWriter(output_file);

            for (int j = 0; j < outputSamples[0, 0].Count; j++)
            {
                file.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}",
                               outputSamples[0, 0][j], outputSamples[0, 1][j], outputSamples[0, 2][j], outputSamples[0, 3][j],
                               outputSamples[1, 0][j], outputSamples[1, 1][j], outputSamples[1, 2][j], outputSamples[1, 3][j]);
            }
            file.Close();
        }
        static void Main(string[] args)
        {
            Dictionary <string, dynamic> dict;
            int i;

            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<master_ip> <slave_ip>] <output_file>] <samples_to_receive]
            string master_ip   = MASTER_IP;
            string slave_ip    = SLAVE_IP;
            string output_file = OUTPUT_FILE;

            if (args.Length >= 2)
            {
                master_ip = args[0];
                slave_ip  = args[1];
            }
            if (args.Length >= 3)
            {
                output_file = args[2];
            }
            if (args.Length >= 4)
            {
                samples_to_receive = Convert.ToInt32(args[3]);
            }

            // Instantiate Socket array.
            sock = new Socket[NumberOfModules];

            // Initialize boundary objects
            LanXIRESTBoundary master = new LanXIRESTBoundary(master_ip);
            LanXIRESTBoundary slave  = new LanXIRESTBoundary(slave_ip);

            // Set sync mode to stand-alone
            master.PutRequestWithPath("/rest/rec/syncmode", "{\"synchronization\": {\"mode\": \"stand-alone\",\"usegps\": false}}");
            slave.PutRequestWithPath("/rest/rec/syncmode", "{\"synchronization\": {\"mode\": \"stand-alone\"}}");

            // Start measurement
            // During this process commands are generally performed on SLAVEs first, finished with MASTER

            // Open the Recorder application on the modules. The same body is sent to both modules, and is prepared in OpenParameters.json
            string openParameters = File.ReadAllText(@"Frame_3050_3160_OpenParameters.json");

            slave.PutRequestWithPath("/rest/rec/open", openParameters);
            master.PutRequestWithPath("/rest/rec/open", openParameters);


            // Prepare generator
            string outputChannelStart = File.ReadAllText(@"Frame_3050_3160_OutputChannelStart.json");

            slave.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            // Configure generator channels
            string outputChannelConfiguration = File.ReadAllText(@"Frame_3050_3160_OutputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            // Start output
            slave.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
            master.PutRequestWithPath("/rest/rec/apply", null);

            // Wait for all modules to be ready; Input in Sampling state, and module in the RecorderOpened state.
            slave.WaitForInputState("Sampling");
            master.WaitForInputState("Sampling");
            slave.WaitForRecorderState("RecorderOpened");
            master.WaitForRecorderState("RecorderOpened");

            // Get TEDS information
            S_Arr = slave.RequestWithPathTeds("/rest/rec/channels/input/all/transducers", "GET", null, false);
            M_Arr = master.RequestWithPathTeds("/rest/rec/channels/input/all/transducers", "GET", null, false);
            for (i = 0; i < S_Arr.Count; i++)
            {
                if (S_Arr[i] != null)
                {
                    Console.WriteLine("Slave Tranducer serialNumber {0}\r\n  type.number {1} ", S_Arr[0].serialNumber, S_Arr[0].type.number);
                }
            }
            for (i = 0; i < M_Arr.Count; i++)
            {
                if (M_Arr[i] != null)
                {
                    Console.WriteLine("Master Tranducer serialNumber {0}\r\n  type.number {1} ", M_Arr[0].serialNumber, M_Arr[0].type.number);
                }
            }

            // Create Recorder configuration on all modules
            slave.PutRequestWithPath("/rest/rec/create", null);
            master.PutRequestWithPath("/rest/rec/create", null);

            // Wait for all modules to be in the RecorderConfiguring state.
            slave.WaitForRecorderState("RecorderConfiguring");
            master.WaitForRecorderState("RecorderConfiguring");

            // Set a configuration for the input channels. Default configuration can be obtained by sending a GET request to /rest/rec/channels/input/default.
            // The body has been prepared and stored in PTPInputStreamingOutputGenerator_InputChannelSetup.json. In this example the setup is identical for the two modules, but it may differ as needed.
            string MasterInputChannelConfiguration = File.ReadAllText(@"Frame_3050_3160_MasterInputChannelSetup.json");
            string SlaveInputChannelConfiguration  = File.ReadAllText(@"Frame_3050_3160_SlaveInputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/channels/input", SlaveInputChannelConfiguration);
            master.PutRequestWithPath("/rest/rec/channels/input", MasterInputChannelConfiguration);

            // Wait until all modules enter the Settled input state
            slave.WaitForInputState("Settled");
            master.WaitForInputState("Settled");

            // Synchronize modules.
            slave.PutRequestWithPath("/rest/rec/synchronize", null);
            master.PutRequestWithPath("/rest/rec/synchronize", null);

            // Wait for all modules to enter the Synchronized input state
            slave.WaitForInputState("Synchronized");
            master.WaitForInputState("Synchronized");

            // Start streaming between internally in the LAN-XI modules.
            slave.PutRequestWithPath("/rest/rec/startstreaming", null);
            master.PutRequestWithPath("/rest/rec/startstreaming", null);

            // Wait for all modules to enter the RecorderStreaming state
            slave.WaitForRecorderState("RecorderStreaming");
            master.WaitForRecorderState("RecorderStreaming");

            // Get the TCP ports provided by each LAN-XI module for streaming samples
            dict = master.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 slavePort = (UInt16)dict["tcpPort"];

            dict = slave.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 masterPort = (UInt16)dict["tcpPort"];

            // Connect to sockets. Let ConnectStreams() handle this.
            ConnectStreams(new string[] { master_ip, slave_ip }, new UInt16[] { masterPort, slavePort });

            // Start measuring.
            slave.PostRequestWithPath("/rest/rec/measurements", null);
            master.PostRequestWithPath("/rest/rec/measurements", null);

            // Wait for modules to enter RecorderRecording state
            slave.WaitForRecorderState("RecorderRecording");
            master.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running.

            // Let Stream() method handle streaming
            Stream();

            // Stop measuring and close sockets for all modules.
            // During this process commands are generaly performed on MASTER module first, then on SLAVEs

            // Stop measurement on modules
            master.PutRequestWithPath("/rest/rec/measurements/stop", null);
            slave.PutRequestWithPath("/rest/rec/measurements/stop", null);

            // Wait for all modules to enter RecorderStreaming state
            master.WaitForRecorderState("RecorderStreaming");
            slave.WaitForRecorderState("RecorderStreaming");

            // Close sockets
            for (i = 0; i < NumberOfModules; i++)
            {
                sock[i].Shutdown(SocketShutdown.Both);
                sock[i].Close();
            }

            // Finish recording
            master.PutRequestWithPath("/rest/rec/finish", null);
            slave.PutRequestWithPath("/rest/rec/finish", null);

            // Stop output
            //            master.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);
            //            slave.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            // Wait for modules to enter the RecorderOpened state
            master.WaitForRecorderState("RecorderOpened");
            slave.WaitForRecorderState("RecorderOpened");

            // Close Recorder application on all modules
            master.PutRequestWithPath("/rest/rec/close", null);
            slave.PutRequestWithPath("/rest/rec/close", null);

            // Wait for modules to enter the Idle state
            master.WaitForRecorderState("Idle");
            slave.WaitForRecorderState("Idle");

            // Write collected samples to output file
            StreamWriter file = new StreamWriter(output_file);

            for (int j = 0; j < outputSamples[0, 0].Count; j++)
            {
                file.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}",
                               outputSamples[0, 0][j], outputSamples[0, 1][j], outputSamples[0, 2][j], outputSamples[0, 3][j], outputSamples[0, 4][j], outputSamples[0, 5][j],
                               outputSamples[1, 0][j], outputSamples[1, 1][j], outputSamples[1, 2][j], outputSamples[1, 3][j]);
            }
            file.Close();
        }
        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <output_file>] <samples_to_receive>]
            string lanxi_ip    = LANXI_IP;
            string output_file = OUTPUT_FILE;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                output_file = args[1];
            }
            if (args.Length >= 3)
            {
                samples_to_receive = Convert.ToInt32(args[2]);
            }

            Dictionary <string, dynamic> dict;

            // Initialize boundary objects
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            // Start measurement
            string syncParametersMaster = "{\"synchronization\": {\r\n\"mode\": \"ptp\",\r\n\"domain\": 11,\"preferredMaster\": true } } }";

            dict = rest.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster);
            if (dict == null)
            {
                Console.WriteLine("\r\nPress ENTER to terminate");
                Console.ReadLine();
                return;
            }
            // Open the Recorder application on the LAN-XI module
            rest.PutRequestWithPath("/rest/rec/open", null);

            // Wait for all modules to be ready; Input in Sampling state, and module in the RecorderOpened state.
            rest.WaitForInputState("Sampling");
            rest.WaitForRecorderState("RecorderOpened");

            // Create Recorder configuration
            rest.PutRequestWithPath("/rest/rec/create", null);
            rest.WaitForRecorderState("RecorderConfiguring");

            // Set a configuration for the input channels. Default configuration can be obtained by sending a GET request to /rest/rec/channels/input/default
            // In this example a JSON file has been prepared with the desired configuration.
            string inputChannelConfiguration = File.ReadAllText(@"InputStreaming_InputChannelSetup.json");

            rest.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration);
            rest.WaitForRecorderState("RecorderStreaming");

            dict = rest.PutRequestWithPath("/rest/rec/channels/input/bridgeNulling",
                                           "{\"channels\" : [{\"nulling\" : \"Automatic\", \"channel\" : 1},{\"nulling\" : \"Automatic\", \"channel\" : 2},{\"nulling\" : \"Automatic\", \"channel\" : 3}]}");

            double val1 = (double)dict["channels"][0]["nullingVoltage"];
            double val2 = (double)dict["channels"][1]["nullingVoltage"];
            double val3 = (double)dict["channels"][2]["nullingVoltage"];

            Console.WriteLine("Nulling: {0}, {1}, {2}", val1, val2, val3);
            // Get the TCP port provided by the LAN-XI module for streaming samples
            dict = rest.GetRequestWithPath("/rest/rec/destination/socket");

            UInt16 port = (UInt16)dict["tcpPort"];

            Console.WriteLine("Streaming TCP port: {0}", port);

            // Start measuring
            rest.PostRequestWithPath("/rest/rec/measurements", null);
            rest.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running

            // Let connectSocketAndStream() method handle socket connection
            // The socket connection may be established while the Recorder was in the "RecorderStreaming" state
            ConnectSocketAndStream(lanxi_ip, port);

            // Stop measuring and close socket
            rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
            rest.WaitForRecorderState("RecorderStreaming");
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();

            rest.PutRequestWithPath("/rest/rec/finish", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Close Recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
            rest.WaitForRecorderState("Idle");

            StreamWriter file = new StreamWriter(output_file);

            for (int i = 0; i < outputSamples[0].Count; i++)
            {
                file.WriteLine("{0}\t{1}\t{2}\t{3}", outputSamples[0][i], outputSamples[1][i], outputSamples[2][i], /*outputSamples[3][i]*/ 0);
            }
            file.Close();
        }