masthead.gif (1891 bytes)

Example programs
sources.htm 3/31/99 Source code is included which allows a TCP/IP host to read a series of registers
using MODBUS/TCP, for use in a number of environments

1. JAVA application run from command line

2. C application for UNIX, run from command line

3. C application for Win32, run from command line

Inspection of the source code will show the similarity - the only differences are
in the interface to the TCP/IP.

Note that these programs were originally released in conjunction with the
Modicon Ethernet TCP/Modbus Plus bridge product

The sources have been moved to a ZIP archive for more consistent handling using different browsers. Look for the files

test1.cpp - Win32 C++

test2.c - UNIX C

test3.java - JAVA

in the archive file sources.zip

test1.cpp - Win32 console app to read registers
============================================================
// test1.cpp 5/23/97

// example Win32 C++ program to read registers from PLC via gateway

// compile with BC45 or BC50
// default settings for Win32 console app
// empty DEF file

#include <winsock.h>
#include <stdio.h>
#include <conio.h>


int main(int argc, char **argv)
{
  if (argc<5)
  {
    printf("usage: test1 ip_adrs unit reg_no num_regs\n"
    "eg test1 198.202.138.72 5 0 10\n");
    return 1;
  }
  char *ip_adrs = argv[1];
  unsigned short unit = atoi(argv[2]);
  unsigned short reg_no = atoi(argv[3]);
  unsigned short num_regs = atoi(argv[4]);
  printf("ip_adrs = %s unit = %d reg_no = %d num_regs = %d\n",
  ip_adrs, unit, reg_no, num_regs);

  // initialize WinSock
  static WSADATA wd;
  if (WSAStartup(0x0101, &wd))
  {
    printf("cannot initialize WinSock\n");
    return 1;
  }

  // set up socket
  SOCKET s;
  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  struct sockaddr_in server;
  server.sin_family = AF_INET;
  server.sin_port = htons(502); // ASA standard port
  server.sin_addr.s_addr = inet_addr(ip_adrs);
  int i;
  i = connect(s, (sockaddr *)&server, sizeof(sockaddr_in));
  if (i<0)
  {
    printf("connect - error %d\n",WSAGetLastError());
    closesocket(s);
    WSACleanup();
    return 1;
  }
  fd_set fds;
  FD_ZERO(&fds);
  timeval tv;
  tv.tv_sec = 5;
  tv.tv_usec = 0;

  // wait for permission to send
  FD_SET(s, &fds);
  i = select(32, NULL, &fds, NULL, &tv); // write
  if (i<=0)
  {
    printf("select - error %d\n",WSAGetLastError());
    closesocket(s);
    WSACleanup();
    return 1;
  }

  // build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn
  unsigned char obuf[261];
  unsigned char ibuf[261];
  for (i=0;i<5;i++) obuf[i] = 0;
  obuf[5] = 6;
  obuf[6] = unit;
  obuf[7] = 3;
  obuf[8] = reg_no >> 8;
  obuf[9] = reg_no & 0xff;
  obuf[10] = num_regs >> 8;
  obuf[11] = num_regs & 0xff;

  // send request
  i = send(s, obuf, 12, 0);
  if (i<12)
  {
    printf("failed to send all 12 chars\n");
  }

  // wait for response
  FD_SET(s, &fds);
  i = select(32, &fds, NULL, NULL, &tv); //read
  if (i<=0)
  {
    printf("no TCP response received\n");
    closesocket(s);
    WSACleanup();
    return 1;
  }

  // read response
  i = recv(s, ibuf, 261, 0);
  if (i<9)
  {
    if (i==0)
    {
      printf("unexpected close of connection at remote end\n");
    }
    else
    {
      printf("response was too short - %d chars\n", i);
    }
  }
  else if (ibuf[7] & 0x80)
  {
    printf("MODBUS exception response - type %d\n", ibuf[8]);
  }
  else if (i != (9+2*num_regs))
  {
    printf("incorrect response size is %d expected %d\n",i,(9+2*num_regs));
  }
  else
  {
    for (i=0;i<num_regs;i++)
    {
      unsigned short w = (ibuf[9+i+i]<<8) + ibuf[10+i+i];
      printf("word %d = %d\n", i, w);
    }
  }

  // close down
  closesocket(s);
  WSACleanup();
  return 0;
}
=========================================================
test2.c - UNIX program to read registers
=========================================================



/*========================================================
test2.c 7/23/97 - UNIX C program to read registers via gateway
  compile using
  cc -o test2 test2.c
  run using
  test2 198.202.138.73 1 2 3
==========================================================*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <netinet/in.h>

/* global data */

int main(int argc, char **argv)
{
  char *ip_adrs;
  unsigned short unit;
  unsigned short reg_no;
  unsigned short num_regs;
  int s;
  int i;
  struct sockaddr_in server;
  fd_set fds;
  struct timeval tv;
  unsigned char obuf[261];
  unsigned char ibuf[261];

  if (argc<5)
  {
    printf("usage: test2 ip_adrs unit reg_no num_regs\n"
    "eg test2 198.202.138.72 5 0 10\n");
    return 1;
  }

  /* confirm arguments */
  ip_adrs = argv[1];
  unit = atoi(argv[2]);
  reg_no = atoi(argv[3]);
  num_regs = atoi(argv[4]);
  printf("ip_adrs = %s unit = %d reg_no = %d num_regs = %d\n",
  ip_adrs, unit, reg_no, num_regs);

  /* establish connection to gateway on ASA standard port 502 */
  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  server.sin_family = AF_INET;
  server.sin_port = htons(502); /* ASA standard port */
  server.sin_addr.s_addr = inet_addr(ip_adrs);

  i = connect(s, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
  if (i<0)
  {
    printf("connect - error %d\n",i);
    close(s);
    return 1;
  }

  FD_ZERO(&fds);
  tv.tv_sec = 5;
  tv.tv_usec = 0;

  /* check ready to send */
  FD_SET(s, &fds);
  i = select(32, NULL, &fds, NULL, &tv);
  if(0)if (i<=0)
  {
    printf("select - error %d\n",i);
    close(s);
    return 1;
  }

  /* build MODBUS request */
  for (i=0;i<5;i++) obuf[i] = 0;
  obuf[5] = 6;
  obuf[6] = unit;
  obuf[7] = 3;
  obuf[8] = reg_no >> 8;
  obuf[9] = reg_no & 0xff;
  obuf[10] = num_regs >> 8;
  obuf[11] = num_regs & 0xff;

  /* send request */
  i = send(s, obuf, 12, 0);
  if (i<12)
  {
    printf("failed to send all 12 chars\n");
  }

  /* wait for response */
  FD_SET(s, &fds);
  i = select(32, &fds, NULL, NULL, &tv);
  if (i<=0)
  {
    printf("no TCP response received\n");
    close(s);
    return 1;
  }

  /* receive and analyze response */
  i = recv(s, ibuf, 261, 0);
  if (i<9)
  {
    if (i==0)
    {
      printf("unexpected close of connection at remote end\n");
    }
    else
    {
      printf("response was too short - %d chars\n", i);
    }
  }
  else if (ibuf[7] & 0x80)
  {
    printf("MODBUS exception response - type %d\n", ibuf[8]);
  }
  else if (i != (9+2*num_regs))
  {
    printf("incorrect response size is %d expected %d\n",i,(9+2*num_regs));
  }
  else
  {
    for (i=0;i<num_regs;i++)
    {
      unsigned short w = (ibuf[9+i+i]<<8) + ibuf[10+i+i];
      printf("word %d = %d\n", i, w);
    }
  }

  /* close down connection */
  close(s);

}

============================================================
test3.java - JAVA program to read registers
============================================================


// test3.java 7/23/97 - JAVA program to read registers via gateway
// compile as
// javac test3.java
// run as
// java test3 aswales1.modicon.com 1 2 3


import java.io.* ;
import java.net.* ;
import java.util.*;

class test3 {
  public static void main(String argv[]) {
    if (argv.length < 4) {
      System.out.println("usage: java test3 dns_name unit reg_no num_regs");
      System.out.println("eg java test3 aswales8.modicon.com 5 0 10");
      return;
    }
    try {
      String ip_adrs = argv[0];
      int unit = Integer.parseInt(argv[1]);
      int reg_no = Integer.parseInt(argv[2]);
      int num_regs = Integer.parseInt(argv[3]);
      System.out.println("ip_adrs = "+ip_adrs+" unit = "+unit+" reg_no = "+
      reg_no+" num_regs = "+num_regs);

      // set up socket
      Socket es = new Socket(ip_adrs,502);
      OutputStream os= es.getOutputStream();
      FilterInputStream is = new BufferedInputStream(es.getInputStream());
      byte obuf[] = new byte[261];
      byte ibuf[] = new byte[261];
      int c = 0;
      int i;

      // build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn
      for (i=0;i<5;i++) obuf[i] = 0;
      obuf[5] = 6;
      obuf[6] = (byte)unit;
      obuf[7] = 3;
      obuf[8] = (byte)(reg_no >> 8);
      obuf[9] = (byte)(reg_no & 0xff);
      obuf[10] = (byte)(num_regs >> 8);
      obuf[11] = (byte)(num_regs & 0xff);

      // send request
      os.write(obuf, 0, 12);

      // read response
      i = is.read(ibuf, 0, 261);
      if (i<9) {
        if (i==0) {
          System.out.println("unexpected close of connection at remote end");
        } else {
          System.out.println("response was too short - "+i+" chars");
        }
      } else if (0 != (ibuf[7] & 0x80)) {
        System.out.println("MODBUS exception response - type "+ibuf[8]);
      } else if (i != (9+2*num_regs)) {
        System.out.println("incorrect response size is "+i+

            " expected"+(9+2*num_regs));
      } else {
        for (i=0;i<num_regs;i++) {
          int w = (ibuf[9+i+i]<<8) + ibuf[10+i+i];
          System.out.println("word "+i+" = "+w);
        }
      }

      // close down
      es.close();
    } catch (Exception e) {
      System.out.println("exception :"+e);
    }
  }
}