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 productThe 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);
}
}
}