I am trying to create a Class that can be used to communicate with a device using Modbus TCP protcol.
Basically you just send a command out on the TCP/IP connection in a certain format.
I have a C++ example and an OCX written by someone else that can do this. I don't know that
much about C++ but it is pretty simple to do. You build a command string and send it out and wait for a response. The C++ and OCX work fine.
I have a packet sniffer and looked at the data inside the packet and it is formated correctly (Using the C++ OCX).
when I try to send the command string in the same format the winsock control formats it to hex and then the command is wrong. If I sniff the packet
from my class the data is not correct. Is there a way to stuff the command string right into the
TCP/IP packet without it reformatting the data?
the command looks like this "00000000000601040000000A" it is in hex. It should look like this in the packet:
"00 00 00 00 00 06 01 04 00 00 00 0A"
But when I send the command it puts it into the packet like this:
"30 30 30 30 30 30 30 30 30 30 30 36 30 31 30 34 30 30 30 30 30 30 30 41"
I cannot figure out how to do this. If anyone has any Ideas or knows something about Socket Programming
I would appreciate some help. I am a VB programmer that does not know much about C++ and how it passes data to a TCP socket. I have
included here the C++ sample I found if anyone can tell me how to do the same in VB it would be a life saver.
Thanks for any help you can provide!!!!!!!

Here's the C++ code Sample. I have the whole OCX project in C++ too if it would help.

// 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;
}



Kris
Software Engineer
Phoenix,AZ