Concept
we have a ship simulator(client) and Modbus controller(Server). Our goal is to develop an emulator(like controller) on my PC. But we have no information about the client(simulator).
Progress
Firstly we checked the actual outputs from the controller(server). There are 7 different variables like engine telegraph, rudder angle and so no.
Secondly, I checked the register numbers of the controller, which store command values. It was from 0 to 7.
Polling server with Modpoll software installed server:
I checked the register type. It was a holding register
I wrote a script to develop a Server like a controller with pymodbus Server. I can not only write specific values on the holding register from 0 to 7, but also there are proper handshake and responses to the simulator(client)
Problem
Client sends a request for reading with register numbers from 256. It means that my Server responds with zero values not with the command values written on the registers from 0 to 7. But the problem is that the simulator(client) shows the changes of the parameters on its Graphical user interface.
Screen shot from wireshark - it shows that clinet(simulator) sends a request with register nuumber from 246:
Client sends a request not only for reading but also for writing and the writing request overwrite the values written by Server (PC).
Question
how is it possible that the simulator receives the command signal by requesting different register numbers? client must send a request with register numbers from 0 to receive command signals.
I cannot understand why the client writes first before reading values from Server. This read request overwrites the values written by Server (pc). The Server (controller or pc) is to send a command signal to the simulator. I have no idea why the simulator first writes some values on sever and read it.
Please advise on this issue.
Best regards
Byeon seongsu.
Related
I am working on a legacy modbus program for an industrial SCADA system.
Currently, the c++ program acts as both a modbus TCP server and client.
Client behaviour:
It reads from a number of vendor PLCs (servers) on site, performs calculations and sends control commands back to the PLCs based on the data received across the site.
Server behaviour:
responds to a variety of TCP read and write requests from web interfaces and laptops on site.
Until now, this has worked fine, but we have recently installed a logging client on the network which polls our program very frequently (sub-second) and this has revealed timing issues: the program can potentially take a very long time in its client loop performing calculations and reading PLC values before acting as a server and responding to incoming requests.
Easy solution would be to split the programs into a modbus server and client instance, and keep them both running on the same embedded PC.
The issue I have is that the remote web interface (HMI) must be able to control the behaviour of vendor PLC 2 and Vendor PLC 2 will only allow one TCP connection from the embedded PC. In the past the program has handled writes requests from the HMI by forwarding them on to the PLC 2 via the open socket.
I'd be keen to gather thoughts on best practices here.
My thinking:
the modbus server program will need to respond to the HMI requests and somehow store the information required for vendor PLC 2, and it will also need to set a status register to inform the modbus client that there is data for vendor PLC 2.
The modbus client program will need to read the status register (and data) from the server and pass this on to vendor PLC 2.
Am I heading in the right direction?
Without having details on your implementation I can only guess the problem is that your program is single-threaded, and delays are caused by waiting responses from PLCs.
So, if my assumption is correct, you need to switch to 'select' function and redesign your software to be totally async. You have to put all sockets (both connected and accepted) in a FDs set and wait events on them.
win32:
https://learn.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-select
linux:
https://www.opennet.ru/cgi-bin/opennet/man.cgi?topic=select&category=2
I've written the same app ages ago on win32 (but without calculations) and it easily processed about 200 PLCs, working on the same machine with SCADA.
I have a device (made in china) that works great but with a very annoying flaw. It's a massage device that will only work if it is connected to the internet at startup. Once it starts, it would work without the internet until it is turned off. So in short, if the internet is down, it will never work or it is impossible to bring this device on an area with no connection.
What I'm planning to do is emulate its server/client communication at start-up by using an old-PC that would run the server emulator software and some DNS re-routing and a WiFi router (using the PC as WAN).
I'll connect the device on the router, and its communication with the Chinese Server is emulated by the PC.
Can anyone give me an idea where to start, tools needed etc? I'm a programmer but new to packet emulation/replay. I've sniffed packets that the device does and its always consistent on every start/restart of the device. Here's the wireshark capture (IMG):
WireShark Packet Capture
You have two tasks, IMHO neither of them requires special tools:
Redirect requests to local address
You need to setup local DNS server and configure it to provide local IP address on hengdetech lookup. I didn't dive into this part, but google has plenty of forums discussing necessary config for different DNS servers.
Device most likely gets DNS server address from DHCP server. So you need to point device to local DNS instead of default one by configure DHCP server (which is run on your router, I suppose).
Once your DHCP configures local DNS and local DNS redirects hedgdete to local IP address, you are free to go to the second part which is
Emulate server behavior
Server must wait for some initial data from client before sending some data back. Such logic doesn't fit well into common "replay packets" tool capabilities, but it's quite easy to implement dumb TCP server with desired functionality on whatever language you like. Open socket, wait for data, send data, not a big deal, isn't it? So I wouldn't bother searching for the right tool, but would creat new instead.
If you need quick proof of concept, that you understand data flow right, before start coding, you may try netcat utility on Unix system for quick server emulation. I did the following once: extracted exchanged payload data from traces and saved as binaries (e.g. file1.bin is sent by server after the first request, file2.bin is sent after the second etc), then used something like this: cat - file1.bin - file2.bin | nc -l -p <local_port> -n. Using cat without dashes results into nc sending all files content to client, once it connects. Dash means "use data from console input rather than file" and they are used only as flow control. cat hangs on the first dash waiting for user input, so pressing ctrl+d proceeds to next file content and sends file1.bin, then hangs on the second dash. So you wait for the first request, press ctrl+d to send file1.bin content, then wait for the second request, press ctrl+d to send file2.bin content and so on.
EDIT
You generally got the idea of extracting data from wireshark traces right, but I want to clarify some subtlenesses.
When you said "saved binaries", did you mean to save individually captured packets as binaries so that netcat could send them to clients as a reply one by one (with the help of dash) ? If so, how do I save captured packets as binaries? Can I just extract them from the wireshark capture files, paste it on a new file and save as binary?
Only payload part of the packet needs to be saved, not the whole packet. TCP header, IP header and so on shouldn't be extracted, only tcp data section should be saved. Check second part of this answer for howto. I suppose, TCP data in your case consists of binary data rather than plain text, so you need to copy it as "raw binary" and use some binary editor allowing to paste "raw binary" into file such as frhed. So yes, you create new file and paste data copied from wireshark into it, so file consists of exactly the same bytes as packet payload.
Another thing to mention, TCP is a stream protocol, one packet doesn't always mean one response message. If you see several TCP packets of maximum size (aka MTU, which is usually 1.5 Kbytes) without PSH flag followed by packet of lesser size with PSH flag, they all contain parts of the single response message, so their payloads should be combined into one "fileX.bin".
This question is not for a concrete implementation of how this is done. It is more about the concept and design of sending information over Internet with some kind of protocol - either TCP or UDP. I know only that sockets are needed, but I am wondering about the rest. For example after a connection is made and you send the information through that, but how does the other end listen for a specific port and does it listen constantly?
Is listening done in a background thread waiting for information to be received? (In order to be able to do other things/processing while waiting for information)
So in essence, I think a real world example of how such an application works on a high level would be enough to explain the data flow. For example sending files in Skype or something similar.
P.S. Most other questions on similar topics are about a concrete implementation or a bug that someone has.
What I currently do in an application is the following using POSIX sockets with the TCP Protocol:
Most important thing is: The most function are blocking functions. So when you tell your server to wait for client connection, the function will block until a connection is established (if you need a server that handles multiple clients at once, you need to use threading!)
Server listens for specific port until a client connects. After the connect, you will get a new socket file descriptor to communicate with the client whilst the initial socket can listen to new connections. My server then creats a new thread to handle that client whilst waiting for new connections on the initial socket. In the new thread the server waits for a request command from the Client (e.g. Request Login Token). After a request was received by the server, the server will gather its informations, packs it together using Googles Protocol Buffers and sends it to the client. The client now either tells the server to terminate the session (if every data is received by the client that it needs) or send another request.
Thats basically the idea in my server. The bigger problem is the way you transmit and receive data. E.g. you cant send structs or classes (at least not via C++) over the wire, you need some kind of serializer and you have to make sure the other part knows how much to receive. So what i do is, first send a 4byte integer over the wire containing the size of the incomming package, then send the package itself using a serializer (in my case Googles Protocol buffers). The other side waits for 4 byte to be available, knowing that this will be the size of the incomming package. After 4 bytes are received, the program waits for exact that amount of data being available on the socket, when available, read the data out of the buffer and deserialize it. When the socket is not receiving data for 30 seconds, trigger a timeout and terminate the connection.
What you always need to be aware of is the endianess of the systems. E.g. a big endian system (e.g. PowerPC) and a little endian system (e.g. x86) will have problems when you send an integer directly over the wire. For example a
0001
on the x86, is a
1000
on the Power PC, thus making a 8 out of a 1. So you should always use functions like ntohl, an htonl, which will convert data from and to host byte order from and to network byte order (network byte order is always big endian).
Hope this kind of helps. I could also provide some code to you if that would help.
I have been working on a telnet/SSH app for the Windows Store and the telnet app has been receiving OOB data on its socket but I can't see it inside the app. I know this because the desktop version of the app is receiving OOB data. I also confirmed that the receive buffer in the Windows Store version is missing the one OOB data byte. In Wireshark I have confirmed that the OOB data is being received by the computer so its just not being forwarded to my app. I know in WinSock you need to set a special parameter to receive OOB data inline but I cannot find any such option for a Windows Store app. Does anyone know of a way to get this OOB data?
Another option would be to tell the telnet server to stop sending the OOB data. Is there to tell it to stop sending it?
For reference, the OOB data is being sent when pressing Ctrl+C. The OOB data byte is 0xFF and is the first byte sent by the server.
Thanks.
It appears that this functionality is not implemented in WinRT. Marking as answered.
http://social.msdn.microsoft.com/Forums/en-US/05a26a4b-e0db-4fed-b5d0-b67a2d9e2b1c/out-of-band-data-using-windowsnetworkingsockets?forum=winappswithnativecode
We're attempting to network between an iphone and a computer (windows 7) using TCP/IP over Wifi. We are having a lot of difficulty setting up this basic network and we were hoping to get some guidance.
Server side:
Currently, we are trying to use MATLAB's tcpip protocol to set up the connection on the computer. We have determined the IP addresses of the phone and the computer and we picked a port number (501), that we are trying to read and write from. We allowed that port number in windows firewall.
In simulink we set up a TCP/IP send block to send out a constant, by double-clicking on that block and selecting the "verify address and port connectivity" button we get the error message:
"The remote address '140.180.....' has been found. However, we are unable to connect to the server at the specified port.
Specify a different port or wait for the current port to become available"
We have tried other port numbers, but gotten the same message.
We have tried using an ad hoc connection between the computer and the iphone to the same effect.
We have also tried other MATLAB scripts to set up the connection (e.g. http://www.mathworks.com/matlabcentral/fileexchange/24524) but we always get and error in the connection
Finally, we tried sending and receiving info over TCP/IP with the same computer using two MATLAB instances running in parallel, but we generally get the same error message.
We even tried UDP...no dice.
Client side (iphone)
We're using NSStream exactly as per this tutorial: http://www.devx.com/wireless/Article/43551/1954
The stream is opened upon a toggle action, and we immediately send a string to the server. We also tried sending a continuous sequence of data with the run loop. One strange bit of behavior is that, after the stream is open for a little while (~1 min), the handleEvent method does seem to get triggered (implying something is received from the server??) because we get a log message corresponding to case NSStreamEventErrorOccurred.
We think the issue lies on the server side, but really don't know enough to be sure or to debug properly. Any help would be very much appreciated.
A long overdue answer to this one: don't network with Windows. We eventually thought to switch over to a mac and lo and behold everything worked properly.