Modbus/TCP and inetd?

I

Thread Starter

Ian Goldby

I'm wondering if it is sensible to write a Modbus/TCP server as an inetd child process. In many ways this simplifies the server, because it has to deal only with one client at a time and all I/O is piped through stdin and stdout (no sockets programming).

<b>But</b> - I wonder if many Modbus clients open and close a connection each time they make a request. With inetd there is something of a performance penalty when a new connection is opened, because inetd has to fork a new instance of the server process each time.

A Google search for "Modbus inetd" returns nothing that seems relevant.

Does anyone have any relevant experience they can offer?
 
It's normal for a client to hold the socket open unless some major error forces it to close. The reason of course is to avoid overhead when polling at a fast rate.

The exception to this is when the client is polling very slowly, in which case it may close the socket as soon as it is done. In some applications the client might only poll once per hour or even once per day, in which case there is no point in leaving the socket open. In that case, the extra overhead of opening the connection isn't typically going to be a problem.

The server needs to deal with multiple simultaneous connections, but they all need to go back to a common data table. A forking server would probably work just fine. I don't know if it has been done before. If it hasn't, it's probably because in most designs the server is part of the application program.

If you made the Modbus server a separate server and the application program (the thing that is going to actually do something interesting) could talk to it via some other fairly simple means (e.g. via a unix socket) then that would probably be useful. The Modbus server could run as a privileged program on port 502, while the application program could talk to it without having to worry about setuid.

I've written several Python programs which have Modbus/TCP servers integrated into them. MS Windows, has no security protection for "well known" server ports, so they could use port 502 directly there. For Linux, the solution that I came up with was to run the program on a higher port and use iptables to redirect 502 to that port. That meant I didn't have to deal with making sure that I was handling all the security implications correctly, since the program runs at a normal user level at all times.
http://sourceforge.net/projects/mblogic/

A Modbus/TCP server that ran as a separate component wouldn't have to deal with that, and so would be a useful way of adding server capabilities to programs.
 
T

Tallak tveide

From what I've seen I would expect close to all clients doing periodic requests on a single tcpip connection. The overhead in question should be no big deal :)

you could see for yourself With wireshark - each connection will be shown clearly
 
L

Lynn August Linse

As others have said, <b>MOST</b> clients hold open the socket.

The one major exception is older versions of the Modicon Momentum PLC which sent only 1 transaction per socket - in part to enable MORE small PLC to work in a peer-to-peer fashion without running out of sockets. For example, if each PLC only supports 8 sockets, then only 8 'peers' could work if they held sockets open. However, by rapidly open/closing (plus putting in semi-clever stack optimizations) dozens or even hundreds of PLC could thrash through those 8 sockets as peers.

So I think you are safe to assume clients don't thrash sockets like that. Just be aware that if you wish to sell to unknown customers out there, you might run across a few with clients which do open/close rapidly.

Regards
- Lynn
 
I
Thanks for all of the advice.

In the end I decided not to use inetd. Yes, writing a proper multi-client non-blocking single-threaded server is more complex, but I think it is worth the investment.

Incidentally, Modbus Request Pro from Soft Control (http://www.soft-control.fr/), which I'm using for some of my testing, <i>does</i> open a new connection for each request.
 
I've written multi-client non-blocking single-threaded Modbus/TCP servers using Python, and it's actually not too difficult. One program that is just a server is about 1100 lines of code and a good deal of that includes options that aren't strictly necessary.

With Python, the ansyncore and twisted libraries do all the hard work. If you were doing this in C on Linux, then you would use epoll (you should be able to find this with Google), which operates a much lower level.

The main problem you will have is if you want the program to do something other than just run a Modbus/TCP server. Again though, if you use Python, twisted is completely designed around this. With twisted I was able to do a Modbus/TCP server, multiple Modbus/TCP clients, soft logic, a web server, a web based HMI, web based system management all in one single process program. The learning curve for twisted is a bit steep, but you can do a lot with it once you get going.

I was also able to use asyncore to do a combined Modbus/TCP server and web based HMI. Asyncore doesn't do as much as twisted, but that does make it a bit easier to get started with. You still however have to get used to the idea of asynchronous I/O, which is somewhat different from the concepts used in multi-threaded/multi-process programming. However, asynchronous I/O is more efficient than the alternatives because it has less overhead.

If you want to have a look at it, my project is at "http://sourceforge.net/projects/mblogic/"
 
I
On OS-9 (my target OS) you implement asynchronous I/O using signals. This makes it very easy to combine handling of I/O with any other stimulus for doing work, including alarms and notifications from other processes.

You tell the OS to send a particular signal as soon as data is available for reading on a particular path/socket. This also works for listen()/accept(), so you never need to block or poll. The program sleeps until it is woken by a signal, so it is very efficient.

Tracking multiple clients is a lot easier than with Win32's overlapped I/O; you don't have to keep track of connection state information because the read itself is a single operation, not split into two parts as with Win32 overlapped I/O.
 
I hadn't realized that OS-9 was still around. I assumed when you mentioned inetd, that it was a Unix style OS.

"Signals" on a Unix style OS are something entirely different, but select and e-poll provide similar capabilities to what you describe. Since Python is a cross platform language, the lower level implementation depends on the platform. On Linux, twisted and asyncore use select and/or e-poll. At the higher level all you see is that your "handle_read" and "handle_write" functions get called when the network stack is ready for them.

The networking capabilities in MS Windows are not very good, which is something that has caused me a bit of grief. Getting something non-trivial to work even reasonably well on that platform takes a lot of effort. They've superficially copied a lot of Unix ideas, but the underlying implementation falls over if you push it very hard.
 
C

curt wuollet

Yes, this is an area where I have found Linux to be robust and certainly "world class". Very sound networking can be built on the distillation of UNIX ideas that Linux supports.

Regards
cww
 
Top