|
I'm working on win ce 6 modbus tcp client server, application is developed for a client server communication and it is working fine. now req is my slave device should respond to the diff slave addresses polled by master/client. Can I just change slave id and establish connection or I need to close previous connection and again establish new one
below is the code, which is working fine for one node, if I polled with other node ID then it gives exception. what change it req to communicate with other node simultaneously. My device should be able to communicate with 32 diff nodes on modbus tcp. Shall I create individual threads for each node but how they will communicate on same port? before establishing connection with other node shall I close previous node?
startupServer(int slaveAddr, const TCHAR * const hostName)
{
int result;
int tcpOption;
struct sockaddr_in hostAddress;
if (isStarted())
return (FTALK_ILLEGAL_STATE_ERROR);
if ((slaveAddr < -1) || (slaveAddr > 255))
return (FTALK_ILLEGAL_ARGUMENT_ERROR);
this->slaveAddr = slaveAddr;
#ifdef _WINSOCKAPI_
WSADATA wsaData;
result = WSAStartup(0x0101, &wsaData);
if (result != 0)
return (FTALK_SOCKET_LIB_ERROR);
#endif
listenSocket = socket(PF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET)
{
shutdownServer();
return (FTALK_OPEN_ERR);
}
#ifdef SO_REUSEADDR
tcpOption = 1; setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR,
(char *) &tcpOption, sizeof (tcpOption));
#endif
hostAddress.sin_family = AF_INET;
if ((hostName == NULL) || (hostName[0] == '\0'))
hostAddress.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
hostAddress.sin_addr.s_addr = inet_addr((char *) hostName);
#if !defined(__VXWORKS__) // We don't support host name resolving with VxWorks
if (hostAddress.sin_addr.s_addr == INADDR_NONE)
{
struct hostent *hostInfo;
hostInfo = gethostbyname((char *) hostName);
if (hostInfo == NULL)
return (FTALK_TCPIP_CONNECT_ERR);
hostAddress.sin_addr = *(struct in_addr *) hostInfo->h_addr;
}
#endif
}
hostAddress.sin_port = htons(portNo);
result = bind(listenSocket, (struct sockaddr *) &hostAddress,
sizeof (hostAddress));
if (result == SOCKET_ERROR)
{
shutdownServer();
switch (socketErrno)
{
#ifdef _WINSOCKAPI_
case WSAEACCES:
return (FTALK_PORT_NO_ACCESS);
case WSAEADDRINUSE:
return (FTALK_PORT_ALREADY_BOUND);
case WSAEADDRNOTAVAIL:
default:
return (FTALK_PORT_NOT_AVAIL);
#else
case ENOTCONN: case EACCES:
return (FTALK_PORT_NO_ACCESS);
case EADDRINUSE:
return (FTALK_PORT_ALREADY_BOUND);
case EADDRNOTAVAIL:
default:
return (FTALK_PORT_NOT_AVAIL);
#endif
}
}
result = listen(listenSocket,
((MAX_CONNECTIONS < SOMAXCONN) ? MAX_CONNECTIONS : SOMAXCONN));
if (result == SOCKET_ERROR)
{
shutdownServer();
return (FTALK_LISTEN_FAILED);
}
return (FTALK_SUCCESS);
}
serverLoop()
{
int iReturnCode = (FTALK_SUCCESS);
int result;
int sockIdx;
int recvResult;
int sendResult;
fd_set fdSet;
timeval timeVal;
SOCKET maxFileDes;
int replyCnt;
int tcpOption;
if (!isStarted())
return (FTALK_ILLEGAL_STATE_ERROR);
FD_ZERO (&fdSet);
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127)
#endif
FD_SET (listenSocket, &fdSet);
#ifdef _MSC_VER
# pragma warning(pop)
#endif
maxFileDes = listenSocket;
for (sockIdx = 0; sockIdx < MAX_CONNECTIONS; sockIdx++)
{
if (connectionSocketArr[sockIdx] != INVALID_SOCKET)
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127)
#endif
FD_SET (connectionSocketArr[sockIdx], &fdSet);
#ifdef _MSC_VER
# pragma warning(pop)
#endif
if (connectionSocketArr[sockIdx] > maxFileDes)
maxFileDes = connectionSocketArr[sockIdx];
}
timeVal.tv_sec = (long) timeOut / 1000L;
timeVal.tv_usec = ((long) timeOut % 1000L) * 1000L;
if (timeOut == 0)
result = select((int) maxFileDes + 1, &fdSet, NULL, NULL, NULL);
else
result = select((int) maxFileDes + 1, &fdSet, NULL, NULL, &timeVal);
if (result == SOCKET_ERROR)
return (FTALK_FILEDES_EXCEEDED);
if (result == 0)
{
TRACELOG1("Slave poll time-out!\n");
dataTablePtr->timeOutHandler();
iReturnCode = (FTALK_REPLY_TIMEOUT_ERROR);
}
if (FD_ISSET (listenSocket, &fdSet))
{
for (sockIdx = 0; sockIdx < MAX_CONNECTIONS; sockIdx++)
{
if (connectionSocketArr[sockIdx] == INVALID_SOCKET)
{
struct sockaddr_in peerAddr;
SOCK_LEN_TYPE peerAddrLen = sizeof(peerAddr);
connectionSocketArr[sockIdx] = accept(listenSocket,
(struct sockaddr *) &peerAddr,
&peerAddrLen);
if (connectionSocketArr[sockIdx] != INVALID_SOCKET)
{
if (!dataTablePtr->validateMasterIpAddr(inet_ntoa(peerAddr.sin_addr)))
{
shutdown(connectionSocketArr[sockIdx], SD_BOTH);
closesocket(connectionSocketArr[sockIdx]);
connectionSocketArr[sockIdx] = INVALID_SOCKET;
TRACELOG2("Connection rejected on slot %d\n", sockIdx);
}
#ifdef TCP_NODELAY
tcpOption = 1; setsockopt(connectionSocketArr[sockIdx],
IPPROTO_TCP, TCP_NODELAY,
(char *) &tcpOption, sizeof (tcpOption));
#endif
#ifdef SO_SNDBUF
tcpOption = MAX_MSG_SIZE;
setsockopt(connectionSocketArr[sockIdx],
SOL_SOCKET, SO_SNDBUF,
(char *) &tcpOption, sizeof (tcpOption));
#endif
#ifdef SO_RCVBUF
tcpOption = MAX_MSG_SIZE;
setsockopt(connectionSocketArr[sockIdx],
SOL_SOCKET, SO_RCVBUF,
(char *) &tcpOption, sizeof (tcpOption));
#endif
#ifdef SO_LINGER
tcpOption = 0; setsockopt(connectionSocketArr[sockIdx],
SOL_SOCKET, SO_LINGER,
(char *) &tcpOption, sizeof (tcpOption));
#endif
TRACELOG2("Connection accepted on slot %d\n", sockIdx);
}
break; }
}
}
for (sockIdx = 0; sockIdx < MAX_CONNECTIONS; sockIdx++)
{
if (connectionSocketArr[sockIdx] != INVALID_SOCKET)
{
if (FD_ISSET (connectionSocketArr[sockIdx], &fdSet))
{
recvResult = recv (connectionSocketArr[sockIdx],
(char *) bufferArr, sizeof (bufferArr), 0);
sendResult = 0;
replyCnt = 0;
if (recvResult >= PREFIX_LEN) {
short dataLen;
dataLen = (short) ((bufferArr[4] << 8) | (bufferArr[5] & 0xFF));
if ((dataLen + PREFIX_LEN) == recvResult)
{
replyCnt = processMessage(&bufferArr[PREFIX_LEN],
recvResult - PREFIX_LEN);
bufferArr[2] = 0; bufferArr[3] = 0; bufferArr[4] = (char) ((replyCnt) >> 8);
bufferArr[5] = (char) ((replyCnt) & 0xFF);
sendResult = send(connectionSocketArr[sockIdx],
(char *) bufferArr,
replyCnt + PREFIX_LEN, 0);
}
}
if ((recvResult < PREFIX_LEN) ||
(sendResult != replyCnt + PREFIX_LEN))
{
shutdown(connectionSocketArr[sockIdx], SD_BOTH);
closesocket(connectionSocketArr[sockIdx]);
connectionSocketArr[sockIdx] = INVALID_SOCKET;
if (recvResult == 0)
TRACELOG2("Disconnected slot %d nicely by other peer.\n",
sockIdx);
else
TRACELOG2("Forced disconnection on slot %d!\n", sockIdx);
}
}
}
}
return iReturnCode;
}
|
|
|
|
|
First you need to tell us what exception you received and also exactly where in the code it occurred.
Veni, vidi, abiit domum
|
|
|
|
|
Not exactly exception but it's not communicating to other node id. If I test it using modscan utility, it works for device id "1" for which communication is established for first time but if trying to communicate with device id "2" then communication is not established.
|
|
|
|
|
I'm afraid that does not help much. You need to use your debugger to find out where the code is failing.
Veni, vidi, abiit domum
|
|
|
|
|
I don't have h/w debug on it. I'm using visual studio 2008, is there any way to debug this issue with visual studio and modscan utility. can I comment all error handling things and just accept client and recv data? will it work?
int ModbusTCPSlave::serverLoop()
{
int iReturnCode = (FTALK_SUCCESS);
int result;
int sockIdx;
int recvResult;
int sendResult;
fd_set fdSet;
timeval timeVal;
SOCKET maxFileDes;
int replyCnt;
int tcpOption;
timeVal.tv_sec = (long) timeOut / 1000L;
timeVal.tv_usec = ((long) timeOut % 1000L) * 1000L;
if (timeOut == 0)
result = select((int) maxFileDes + 1, &fdSet, NULL, NULL, NULL);
else
result = select((int) maxFileDes + 1, &fdSet, NULL, NULL, &timeVal);
{
{
{
struct sockaddr_in peerAddr;
SOCK_LEN_TYPE peerAddrLen = sizeof(peerAddr);
connectionSocketArr[sockIdx] = accept(listenSocket,
(struct sockaddr *) &peerAddr,
&peerAddrLen);
recvResult = recv (connectionSocketArr[sockIdx],
(char *) bufferArr, sizeof (bufferArr), 0);
sendResult = 0;
replyCnt = 0;
if (recvResult >= PREFIX_LEN) {
short dataLen;
dataLen = (short) ((bufferArr[4] << 8) | (bufferArr[5] & 0xFF));
if ((dataLen + PREFIX_LEN) == recvResult)
{
replyCnt = processMessage(&bufferArr[PREFIX_LEN],
recvResult - PREFIX_LEN);
bufferArr[2] = 0; bufferArr[3] = 0; bufferArr[4] = (char) ((replyCnt) >> 8);
bufferArr[5] = (char) ((replyCnt) & 0xFF);
sendResult = send(connectionSocketArr[sockIdx],
(char *) bufferArr,
replyCnt + PREFIX_LEN, 0);
}
}
if ((recvResult < PREFIX_LEN) ||
(sendResult != replyCnt + PREFIX_LEN))
{
shutdown(connectionSocketArr[sockIdx], SD_BOTH);
closesocket(connectionSocketArr[sockIdx]);
connectionSocketArr[sockIdx] = INVALID_SOCKET;
if (recvResult == 0)
TRACELOG2("Disconnected slot %d nicely by other peer.\n",
sockIdx);
else
TRACELOG2("Forced disconnection on slot %d!\n", sockIdx);
}
return iReturnCode;
}
|
|
|
|
|
Visual Studio contains a program debugger as standard. If you have not used it before then now is the time to learn.
Veni, vidi, abiit domum
|
|
|
|
|
will the above code with commented error handling will resolve the issue...so that i can communicate with multiple device ids like 1, 2, 3..32
|
|
|
|
|
Member 10296418 wrote: will the above code with commented error handling will resolve the issue Sorry, but I cannot answer that question. You need to try the code in your debugger to see exactly what is happening. In general you should be able to accept any number of connections, and manage the communication between server and clients quite easily.
Veni, vidi, abiit domum
|
|
|
|
|
Using modscan if I poll for same IP with diff device ID application should responds to every device id, In above code I commented checking INVALID_SOCKET..and recv message is called so that messages will be received with diff device IDs. will it work?
|
|
|
|
|
Hi Member 10296418,
to avoid the exception you need to close the Socket Connection and reopen the same. you can create multiple virtual ports and try creating multiple threads for the socket connection. And also give 5MS delay after closing the connection.
Hope this helps .
Regards,
Shyam Kodase
Feb 13 2014
|
|
|
|
|
Dear friends,
I am a POS developer, my question is im send some request to some different server then that person send me to resonse with some EOT i want get this response without this EOT how can i do this using C..please help me.
thank you.
|
|
|
|
|
You can't, if the message contains that character or sequence then you need to deal with it.
Veni, vidi, abiit domum
|
|
|
|
|
how can i deal with that..
|
|
|
|
|
How can you deal with what? Remember, we cannot see your code or read your mind, so we have no idea what the problem may be unless you provide clear details.
Veni, vidi, abiit domum
|
|
|
|
|
yes im sorry...
server_send_packet(sockt,DownCofig_PARAM_OBJ.transmitData);
//Think some third party give me to some library and i want to send my data to that library then that //library some data called "transmitData" .Then i send this data to the server.
server_rcv_packet(sockt,rcv,300,0);
//then server response i take to this rcv buffer and send to library.So this rcv data has EOT(0x04) i want read this rcv buffer data until this EOT so how can i do this.
|
|
|
|
|
You should use a loop to keep calling recv until there is no more data, or the EOT character has been received. You can then remove the EOT character from the buffer and send the remainder of the message to the library.
Veni, vidi, abiit domum
|
|
|
|
|
Dear friend don't get mis understand me iam new to this ....i already try to your solution,but i did that rcv buffer length ,how can i identify this EOT character i mean if there is some standard way or something
|
|
|
|
|
You need to search the receive buffer for it.
Veni, vidi, abiit domum
|
|
|
|
|
Thank u very much my dear friend really appreciate your help.
|
|
|
|
|
Our C++ 5.0 code does something like this:
if the excel dispatch is successfully created, it then exports data, etc...
...
then calls these functions:
xlsApp.SetDisplayAlerts(TRUE);
xlsApp.SetVisible(TRUE);
xlsApp.SetUserControl(TRUE);
This has always worked to display the excel spreadsheet in the foreground.
Now, testing on Windows Server 2008, the excel spreadsheet is created, but in the background.
Any suggestions?
Thanks.
|
|
|
|
|
I found a simple workaround using FindWindow() and SetForegroundWindow to force the Excel window to the foreground. Note, the application parameter of FindWindow() needs to be "XLMAIN".
HWND xlsHWnd = FindWindow(_T("XLMAIN"), NULL);
SetForegroundWindow(xlsHWnd);
|
|
|
|
|
Hello there,
I have statically linked OpenCV libs to a Win32 console application in Visual Studio 2012. I got the webcam and face detection working awesome.
I am using the "haarcascade_frontalface_alt.xml" for face detection purpose and this file is currently placed in the folder where the exe is present.
I want to link in this xml to project i.e., compile into the project and then use it at run time.
i.e., extract xml data from the compiled in xml file and load it to the corresponding OpenCV function.
Does anyone has suggestions on how to do this?
Any sample code will be helpful.
Thanks in advance.
|
|
|
|
|
You could create a custom resource inside the exe, and then read it at runtime.
Check out: Creating a Resource[^]
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I need to write some code (using C++/VS2010/Windows7), that can talk to a hardware I/O module (PhoenixContact Axioline F Bus Coupler) which is connected via Ethernet and, as usual, have never done this before.
I just need someone to point me in the right direction so I can get started, if possible please...
There's plenty of stuff on MSDN, eg. Quote: Getting Started with Winsock , but I don't have the confidence to dive right in just yet.
|
|
|
|
|
Actually "Getting Started with Winsock" is a great resource, in my opinion. You could try the examples to get acquainted. However, knowing how socket works on Windods, could be not enough. You probably should have a look at the open source project "Simple Open EtherCAT master"[^] (I know it's Linux).
Veni, vidi, vici.
|
|
|
|
|