Examples - Socket communication (Advanced)

Top  Previous  Next

//-----------------------------------------------------------------------------

// test.vpl, created 2001-10-31 12:31

//

// This program connects to and "echo server" on port 5005.

// It sends a packet, waits for the echo, and repeats this process 100 times.

// After 100 frames, the socket disconnects and automatically attempts to reconnect

// to start the cycle again. Activating the 'restart' input forces an immediate 

// reconnection.

//

// Server Requirements:

// - The server must run the 'echos.exe' application (source: echos.c), found

//   in the SO API example folder.

// - The server PC requires an externally accessible IP address with port forwarding

//   and firewall rules configured to allow traffic on port 5005.

//

// Configuration:

// - Set the 'host' variable to the server's IP or hostname (default: "rtcu.dk").

//-----------------------------------------------------------------------------

INCLUDE rtcu.inc
 
//  Input variables that can be configured via the configuration dialog (These are global)
VAR_INPUT
  restart : BOOL R_EDGE; | Restart connection (disconnect/connect)
END_VAR;
 
//  Output variables that can be configured via the configuration dialog (These are global)
VAR_OUTPUT
  toggle   : BOOL; | LED that indicate when data is received from echo host
  cnetwork : BOOL; | LED that indicates that a Cellular network connection is present.
END_VAR;
 
//  These are the global variables of the program
VAR
  sockrcv : sockReceive;   // Receive data on a socket
  soccon   : sockConnection; // Create a socket connection
  id       : SINT; // ID of the connection
  buffer   : ARRAY[0..300] OF SINT; // Receive buffer
  teststr1 : STRING :="Hello world. This is a test of the RTCU SOCKET Interface";
  teststr2 : STRING :="Hello world. The RTCU Concept is the most powerfull Cellular Telemetry platform in the world!!";
  host     : STRING :="rtcu.dk"; // The echo host (can also be a dotted format IP address)
  port     : int :=5005; //The echo host port number.
  iter     : DINT; // Number of iterations
  rc       : INT; // Return codes from socket calls
END_VAR;
 
 
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
PROGRAM test;
DebugMsg(message:="Cellular Network Socket test-program started.");
 
// Turn on power to Cellular module
gsmPower(power:=ON);
 
// Open the Cellular network connection
rc:=netOpen(iface:=_NET_IFACE_CELLULAR);
DebugFmt(message:="netOpen()=\1",v1:=rc);
 
// Wait for Cellular network connected (after this, we are connected to the Internet)
WHILE NOT netConnected(iface:=_NET_IFACE_CELLULAR) DO
  DebugMsg(message:="Waiting for Cellular network connection");
  Sleep(delay:=2500);
END_WHILE;
 
// Connect to the echo host, using port 5005
id:=sockConnect(ip:=sockIPFromName(str:=host),port:=port);
 
DebugFmt(message:="sockConnect()=\1",v1:=id);
 
// Initialize the sockConnection() functionblock
soccon.id:=id;
 
// And intialize the socket receiver
sockrcv.id:=id;
sockrcv.data:=ADDR(buffer);
sockrcv.maxsize:=SIZEOF(buffer);
 
BEGIN
 cnetwork:=netConnected(iface:=_NET_IFACE_CELLULAR);
 soccon(); // Update sockConnection() functionblock
 sockrcv(); // Update sockReceive() functionblock
 
// If restart switch activated, disconnect the old connection, and make a new one
IF restart THEN
    // Disconnect old socket
    sockDisconnect(id:=soccon.id);
    // Lookup IP address of echo host, and make a connection to it
    id:=sockConnect(ip:=sockIPFromName(str:=host),port:=port);
    DebugFmt(message:="sockConnect()=\1",v1:=id);
    // Update sockConnection()/sockReceive() functionblocks with the new connection ID
    soccon.id:=id;
    sockrcv.id:=id;
END_IF;
 
// If connection status changed on socket
IF soccon.changed THEN
    // ...and we are now connected, go send data to echo host
    // (This will "prime" the conversation, after this the data are "re-used"
    // as the echo server gets its own data back again (see sockrcv.ready below))
    IF soccon.Connected THEN
      DebugMsg(message:="Socket connected");
      DebugMsg(message:=sockIPToName(ip:=soccon.remoteIP));
      strToMemory(dst:=ADDR(buffer),str:=teststr1,len:=strLen(str:=teststr1));
       rc:=sockSend(id:=id,data:=ADDR(buffer),size:=strLen(str:=teststr1));
      DebugFmt(message:="sockSend rc=\1",v1:=rc);
      strToMemory(dst:=ADDR(buffer),str:=teststr2,len:=strLen(str:=teststr2));
       rc:=sockSend(id:=id,data:=ADDR(buffer),size:=strLen(str:=teststr2));
      DebugFmt(message:="sockSend rc=\1",v1:=rc);
       iter:=0;
    ELSE
      // ...and we are now disconnected, go make a new connection attempt
      DebugMsg(message:="Socket disconnected");
      // Disconnect old socket
      sockDisconnect(id:=soccon.id);
      //let the sockConnection() see that we are disconnected.
       soccon();
      // Lookup IP address of echo host, and make a connection to it
       id:=sockConnect(ip:=sockIPFromName(str:=host),port:=port);
      DebugFmt(message:="sockConnect()=\1",v1:=id);
      // Update sockConnection()/sockReceive() functionblocks with the new connection ID
       soccon.id:=id;
       sockrcv.id:=id;
    END_IF;
END_IF;
 
// If received data on the socket (echo data from echo server)
IF sockrcv.ready THEN
    iter:=iter+1;
    DebugFmt(message:="\4 - data received len=\1", v4:=iter, v1:=sockrcv.size);
    toggle:=NOT toggle; // Change the state of the LED
    // After 100 iterations, we Diconnect the socket. This will activate
    // the code above (soccon.changed) and then try to connect the socket again
    IF iter<100 THEN
      // Send the data we just received from the echo server, back again
      sockSend(id:=id, data:=ADDR(buffer), size:=sockrcv.size);
    ELSE
      sockDisconnect(id:=soccon.id);
    END_IF;
END_IF;
END;
 
END_PROGRAM;