I am working on a project involving a microcontroller communicating to a PC via Modbus over TCP. My platform is an STM32F4 chip, programming in C with no RTOS. I looked around and found LwIP and Freemodbus and have had pretty good success getting them both to work. Unfortunately, I'm now running into some issues which I'm not sure how to handle.
I've noticed that if I establish connection, then lose connection (by unplugging the Ethernet cable) I will not be able to reconnect (once I've plugged back in, of course). Freemodbus only allows one client and still has the first client registered. Any new clients trying to connect are ignored. It won't drop the first client until after a specific timeout period which, as far as I can tell, is a TCP/IP standard.
My thoughts are...
I need a Modbus module that will handle multiple clients. The new client request after communication loss will be accepted and the first client will eventually be dropped due to the timeout.
How do I modify Freemodbus to handle this? Are there examples out there? I've looked into doing it myself and it appears to be a decently sized project.
Are there any good Modbus packages out there that handle multiple clients, are not too expensive, and easy to use? I've seen several threads about various options, but I'm not sure any of them meet exactly what I need. I've had a hard time finding any on my own. Most don't support TCP and the ones that do only support one client. Is it generally a bad idea to support multiple clients?
Is something wrong with how I connect to the microcontroller from my PC?
Why is the PC changing ports every time it tries to reconnect? If it kept the same port it used before, this wouldn't be a problem
Should I drop the client from Freemodbus as soon as I stop communicating?
This seems to go against standards but might work.
I'm leaning towards 1. Especially since I'm going to need to support multiple connections eventually anyways. Any help would be appreciated.
Thanks.
If you have a limit on the number of modbus clients then dropping old connections when a new one arrives is actually suggested in the modbus implementation guide (https://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf)
Nevertheless a mechanism must be implemented in case of exceeding the number of
authorized connection. In such a case we recommend to close the oldest unused
connection.
It has its own problems but everything is a compromise.
Regarding supporting multiple clients...if you think about modbus/rs server - it could only ever have one master at a time. Then replace the serial cable with TCP and you see why it's not uncommon to only support one client (and of course it's easier to program). It is annoying though.
Depending on what you are doing you wont need the whole modbus protocol and implementing the parts you do need is pretty easy. Of course if you have to support absolutely everything its a different prospect. I haven't used freemodbus, or any other library appropriate to your setup, so I can't help with suggestions there.
Regarding the PC using different TCP source port each time - that is how TCP is supposed to work and no fault on your side. If it did reuse the same source port then it wouldn't help you because e.g. sequence numbers would be wrong.
Regarding dropping clients. You are allowed to drop clients though its better not to. Some clients will send a modbus command, notice the connection has failed, reconnect, but not reissue the command. That may be their problem but still nicer to not see it that often where possible. Of course things like battery life might make the calculation different.
Related
I know this should be obvious, but I have found far too many DIFFERENT answers and the ones I've tried all fail (sometimes or all the time), so...
We are working on a service and some applications that run at startup on a Windows 10 computer that performs an automatic login. The service and applications require Windows sockets for TCP, UDP and Multicast. Most of the time, our programs fail because they get errors about the network not being ready and such. Currently, we work around this by just adding a dumb, fixed length delay time before attempting to start, but we would prefer to start as soon at the network is ready to be used.
Our most recent attempt was to wait on the LanmanWorkstation (Workstation) service, but that generally reports it is running/ready before the sockets functions will succeed. I have also seen suggestions to use LanmanServer (Server) or Netman (Network Connections) or maybe even Tcpip (TCP/IP Protocol Driver), but I cannot find anything definitive. One would think this is a common requirement, so why would Microsoft make the info so difficult to find?
Ahem. Does any know a definitive method for a service or application to wait until winsock functions will succeed before using them? Short of a spin wait on a failing winsock function, of course!
This may not be in the right location, so tell me and I'll move it.
I am a recent EE grad and I was hired to build a system that exists on a SoC with a simple 32-bit processor. The system basically monitors several external devices and performs some DSP on it, and then is supposed to send the results using a WiFi device (in my case I have the ESP8266 using UDP) to an email server for logging/notification.
I have been trying to find a library that I can use, but my uC can only program in C and I have it set up for UDP, and everything is in C++ using some other protocol, or something else completely.
I am great at DSP, decent at SoC's and uC's, but when it come to this email server communication thing I am at a loss.
I have successfully configured everything for the sensors, the datapath, the DSP, and connected the system to my WiFi via UDP, but I have yet to figure out how to send data to any servers.
Could someone help me understand how I should go about this?
I have looked into some simple SMTP commands such as HELO, MAIL, RCPT, DATA, etc. but I cannot understand how I actually should implement them in my code.
When I send out the WiFi data via UDP what type of data do I send and how do I format it? Do I need to send any other kind of flags? How should I expect the response? I also know the data has to be transformed into base 64 which is confusing me further.
I am also not super familiar with UDP to begin with, I have been using libraries that are part of the SoC's default library to connect to my WiFi.
I know these may either seem like obvious or stupid questions but it is were I no longer have any knowledge, and everything I find online doesn't make sense, or doesn't attempt to explain it, just gives a pre-made solution
I have found the RFC2821 but it doesn't get any clearer.
I know that's a lot but any help at all would be a lifesaver!
Since you are asking this question, I'm assuming that you are not booting and running an OS suitable for micro-controllers such as an embedded variant of Linux or such. If you were, you would simply be able to take advantage of possibly built in applications or other existing code.
But you don't mention having written an Ethernet stack, so are you using some other library or operating environment which might have some of the functionality needed for an implementation of SMTP?
If you don't and really do need to write your own SMTP client to run directly on the processor you are using, then you should be able to find plenty of examples of source code for this. A quick google search of How To Write an SMTP client showed a few articles with some example code. One article seems to be an exact hit, but you need to look at it further.
However, I would highly suggest just sitting down with a telnet client and connect to an SMTP server you are allowed to use and try the commands you need to just send a message. If you only need to send text, you don't need to get involved in MIME encoding or anything like that.
C Language TCP server/client.. I want to assign a new socket for a particular client which requested my server from 8080 lets say the new socket is 8081 to get further request, and want to free the previous socket(8080) so that the other clients will request my server from 8080. is there any way of doing it in C language. (OS Ubuntu) Thanks
Your problem statement is incorrect. You can't do this even if you wanted to. The way that TCP sockets work is that accept() gives you a new socket for the incoming client connection, on the same port you are listening to. That's all you need and it's all you can get. You can't 'allocate a new socket' to the client on a new port without engaging in another TCP handshake with him, which would be nothing but a complete waste of time when you already have a connection to him. This does not preclude another connection bring accepted while this one is open. You need to read a TCP Sockets networking tutorial.
Mat and EJP have said the pertinent things above, but I thought it might help others to describe the situation more verbosely.
A TCP/IP connection is identified by a four-tuple: target IP address, target TCP port number, source IP address, and source TCP port number. The kernel will keep track of established connections based on these four things. A single server port (and IP address) can be connected to thousands of clients at the same time, limited in practice only by the resources available.
When you have a listening TCP socket, it is bound to some IP address (or wildcard address) and TCP port. Such a socket does not receive data, only new connections. When accept() is called, the server notes the new four-tuple of the connection, and hands off the file descriptor that represents that connection (as the accept() return value). The original socket is free to accept new connections. Heck, you can even have more than one thread accepting new connections if you want to, although establishing new connections in Linux is so fast you shouldn't bother; it's just too insignificant to worry about.
If establishing the connection at application level is resource-intensive -- this is true for for example encrypted connections, where agreeing to an encryption scheme and preparing the data structures needed takes typically several orders of magnitude more CPU resources than a simple TCP connection --, then it is natural to wish to avoid that overhead. Let's assume this is the point in OP's question: to avoid unnecessary application-level connection establishment when a recent client needs another connection.
The preferred solution is connection multiplexing. Simply put, the application-level protocol is designed to allow multiple data streams via a single TCP connection.
The OP noted that it would be necessary/preferable to keep the existing application protocol intact, i.e. that the optimization should be completely on the server side, transparent to the clients.
This turns the recommended solution to a completely new direction. We should not talk about application protocols, but how to efficiently implement the existing one.
Before we get to that, let's take a small detour.
Technically, it is possible to use the kernel packet filtering facilities to modify incoming packets to use a different port based on the source IP address, redirecting requests from specific IP addresses to separate ports, and making those separate ports otherwise inaccessible. Technically possible, but quite complex to implement, and with very questionable benefits.
So, let's ignore the direction OP assumed would bring the desired benefits, and look at the alternatives. Or, actually, the common approach used.
Structurally, your application has
- A piece of code accepting new connections
- A piece of code establishing the application-level resources needed for that connection
- A piece of code doing the communication with the client (serving the response to the client, per the client's request)
There is no reason for these three pieces to be consecutive, or even part of the same code flow. Use data structures to your advantage.
Instead of treating new incoming connections (accept()ed) as equal, they can be simply thrown into separate pools based on their source IP addresses. (Or, if you are up to it, have a data structure which clusters source IP addresses together, but otherwise keeps them in the order they were received.)
Whenever a worker completes a request by a client, it checks if that same client has new incoming connections. If yes, it can avoid most if not all of the application-level connection establishment by checking that the new connection matches the application-level parameters of the old one. (You see, it is possible that even if the source IP address is the same, it could be a completely different client, for example if the clients are under the same VPN or NATted subnet.)
There are quite a few warts to take care of, for example how to keep the priorities, and avoid starving new IP addresses if known clients try to hog the service.
For protocols like HTTP, where the client sends the request information as soon as the server accepts the connection, there is an even better pattern to apply: instead of connection pools, have request pools. A single thread or a thread pool can receive the requests (they may span multiple packets in most protocols), without acting on them; only detecting when the request itself is complete. (A careful server will limit the number of pending requests, and the number of incomplete request, to avoid vulnerability to DOS.)
When the requests are complete, they are grouped, so that the same "worker" who serves one request, can serve another similar request with minimal overhead. Again, some careful thought is needed to avoid the situation where a prolific client hogs the server resources by sending a lot of requests, but it's nothing some careful thought and testing won't resolve.
One question remains:
Do you need to do this?
I'd wager you do not. Apache, which is one of the best HTTP servers, does not do any of the above. The performance benefits are not considered worth the extra code complexity. Could you write a new HTTP server (or a server for whatever protocol you're working with), and use a scheme similar to above, to make sure you can use your hardware as efficiently as possible? Sure. You don't even need to be a wizard, just do some research and careful planning, and avoid getting caught in minute details, keeping the big picture in mind at all times.
I firmly believe that code maintainability and security is more important than efficiency, especially when writing an initial implementation. The information gained from the first implementation has thus far always changed how I perceive the actual "problem"; similar to opening new eyes. It has always been worth it to create a robust, easy to develop and maintain, but not necessarily terribly efficient implementation, for the first generation. If there is someone willing to support the development of the next generation, you not only have the first generation implementation to compare (and verify and debug) against, but also all the practical knowledge gained.
That is also the reason old hands warn so often against premature optimization. In short, you end up optimizing resource waste and personal pain, not the implementation you're developing.
If I may, I'd recommend the OP back up a few steps, and actually describe what they intend to implement, what the observed problem with the implementation is, and suggestions on how to fix and avoid the problem. The current question is like asking how to better freeze a banana, as it keeps shattering when you hammer nails with it.
I'm currently in an early phase of developing a mobile app that depends heavily on timestamps.
A master device is connected to several client devices over wifi, and issues various commands to these. When the client devices receive commands, they need to mark the (relative) timestamp when the command is executed.
While all this is simple enough, I haven't come up with a solution for how to deal with clock differences. For example, the master device might have its clock at 12:01:01, while client A is on 12:01:02 and client B on 12:01:03. Mostly, I can expect these devices to be set to similar times, as they sync over NTP. However, the nature of my application requires ms precision, so therefore I would like to safeguard against discrepancies.
A short delay between issuing a command and executing the command is fine, however an incorrect timestamp of when that command was executed is not.
So far, I'm thinking of something along the line of having the master device ping each client device to determine transaction time, and then request the client to send their "local" time. Based on this, I can calculate what the time difference is between master and client. Once the time difference is know, the client can adapt its timestamps accordingly.
I am not very familiar with networking though, and I suspect that pinging a device is not a very reliable method of establishing transaction time, since a lot factors apply, and latency may change.
I assume that there are many real-world settings where such timing issues are important, and thus there should be solutions already. Does anyone know of any? Is it enough to simply divide response time by two?
Thanks!
One heads over to RFC 5905 for NTPv4 and learns from the folks who really have put their noodle to this problem and how to figure it out.
Or you simply make sure NTP is working properly on your servers so that you don't have this problem in the first place.
TL;DR available at the bottom
I've been trying to figure out a way to get two laptops (both running Ubuntu) to be able to pass basic messages back and forth without the need for them to be connected via a wireless network,either by an AP or ad-hoc. I want to reiterate here that ad-hoc networking is not what I'm looking for, I've seen many similar questions here with that as the answer.
I guess what I'm asking is: how do I achieve this? All I really need is for one computer to be able to send a packet, and then for another to pick it up via a packet sniffer of some kind.
Currently: I have both laptops in monitor mode (via a mon0 interface created from aircrack-ng's airmon-ng)so that they can sniff nearby traffic (with Wireshark, tcpdump,tcpcump.org's sample libpcap code, and opening a raw socket and just printing out all the packets. I tried each just because I thought one could be doing something differently/leaving something out). I also have a very basic program that consists of opening a raw socket to send crafted ethernet frames out to the air, but I can't get my two machines to see the other's packets. The sniffer running on each machine can only see the packets going out of that machine (in addition to nearby beacons/control traffic from wifi in the area).
Some things to note that might be important are:
-the packets I'm sending out appear in Wireshark (only on the sending machine) as malformed 802.11 packets (probably because I'm just filling them with junk data for now). I was under the impression that my other laptop would also see them as malformed packets, but it gets nothing
-the sockets I'm using are from a call to socket(PF_PACKET,SOCK_RAW,ETH_P_ALL). Raw sockets are something I just recently was aware of, so I could be misunderstanding how they work, but my impression is that I can craft a layer 2 packet by hand and ship out straight out to the wire/air.
If you're curious as to why I want to do something like this, it's part curiosity, part research for a project I'm working on. I want to streamline / automate the process of setting up an ad-hoc network, and what I'm trying to do here is for the laptops to do a small exchange to figure out the specifics of the adhoc network they are about to create and then make/join that network automatically, instead of either one person explicitly setting up the network OR having both people pre-decide the name, etc of the network and have both computers constantly trying to connect to that specific one.
I'm more interested if I'm going about this process in the right way rather than if my code works or not, if someone thinks me posting my (very basic, taken from another post on Stack Overflow) raw socket code will help, I can.
Edit: I am more than happy to post a complete set of code with instructions if I can get this working. I couldn't find much helpful info on this topic on the internet, and I'd love to put it up for future people trying to do the same thing.
TL;DR I want to send out a packet from one laptop and pick it up on another via a packent sniffer of some sort. No wifi network or ad-hoc network involved. Something akin to spoofing an AP's beacon frame (or similar) for the purpose of sending small amounts of data.
Edit 2:After some thought, perhaps what I'm looking for is some kind of raw 802.11 use? Having direct control of the wifi radio? Is such a thing possible?
I found out I was able to send packets out through my monitor mode interface as long as I had correct 802.11 with radiotap headers. I think the problem I was originally experiencing (not being able to sniff the packets) was because they were malformed and thus not actually getting sent out.
I was able to accomplish this by adapting the example code found here, courtesy of someone named Evan Jones, except I did not need to use an Atheros based card or Madwifi drivers, everything worked fine with the mon0 interface created with aircrack-ng.
I am certain that Apple Mac do this. Apple call it 'bonjour'. There may well be a proper IETF spec for it. This is an Article on Bonjour this is Wikipedia on an open component of bonjour which might help get you moving.