I am working with NB-IoT Modem - Quectel BC95 that will be used in a simple IoT sensor that will periodically (Once per hour) send measurements to our server.

Because of the restriction in place by the service operator, I can't use the hardware implementation of CoAP/M2M (Neil Messaging Protocol - as they call "it") and I am stuck with Raw UDP Messaging (Socket).

I want to keep it real simple and keep the "size" of the data at a minimum but still, be prepared that server can expect thousands of these sensors to stream data. I was thinking about just a simple JSON/CSV values inside a UDP message but have no idea if this solution is "Robust" or Secure enough.

Can you please point me into the right direction? Is there any "standardized" way to send data from IoT sensors to a server while using just a simple UDP socket and is easy to implement on the MCU side (We are very resource limited)?

  • the UDP protocol does not have a guaranteed delivery mechanism
    – jsotola
    Commented Oct 26, 2018 at 5:52
  • UDP is great if you're ok with losing packets now and then. It may work for you with sensors continously sending data. Commented Oct 26, 2018 at 9:20
  • 2
    What "restriction in place by the service operator" could prevent you to use a well-defined standard protocol? Rolling your own will just mean to re-invent what has already been invented. Eg. for privacy you'd have to use DTLS over UDP (coaps://), for reliability you'll need sequence numbers and retransmissino (part of CoAP), etc. Commented Oct 26, 2018 at 14:31
  • What security protocol will you use to validate the data is real and not faked?
    – SeanJ
    Commented Oct 28, 2018 at 22:46
  • Why dont use mqtt?
    – behroozbc
    Commented Jan 18, 2022 at 22:09

3 Answers 3


Well, it really depends.

First thing is what are really your constraints. You said the operator doesn't allow you to use CoAP/M2M so you have to stick with raw UDP but there are many other protocol stacks supported by the Quectel BC95, according to this official datasheet, it can use all of these:

  • IPv4
  • IPv6
  • UDP
  • CoAP
  • LwM2M
  • Non-IP
  • DTLS
  • TCP
  • MQTT

So you can for example use raw TCP/IP or the mentioned by @behroozbc MQTT which basically wraps over TCP as well. But since you're not using it and talking about UDP I'm assuming you are allowed only UDP or all the protocol stacks not wrapped over TCP (which is probably the case since the three-way handshake of TCP is considered the most energy consuming part of the communication and is probably why you're not allowed to use it). Unfortunately this modem doesn't support MQTT-SN based on UDP, so, for the sake of universality of the question, let's stick with raw UDP.

UDP and TCP were developped for very different purposes so there is quite little overlapping when it comes to what works well using them. And regular quick sending a probably big data set every hour while trying to use as little energy as possible is not suitable for raw UDP.

But you know, when there is a no solution, you build one.

You can recreate some of the characteristic TCP features using UDP. Let's talk about each feature/problem separately.

Data corruption

Although data corruption is not really a frequent problem with UDP (well, at least not any more than in TCP) but can still happen. This should be easily manageable by simply adding a digest checksum to the message. A checksum can also be a part of the of the UDP header, but it's not obligatory, I don't know if that modem uses it.

If for some weird reason data corruption would tend to happen quite often you can think of implementing some simple Cyclic Redundancy Check like those used in CDs letting them be read even though having scratches.

Packet loss

That's the main problem with UDP - packets don't usually get changed but they do get lost often.

You can implement your own modified version of the three-way handshake. And here comes really handy the fact that the data is supposed to be sent cyclically every hour.

Every packet should contain a simplified timestamp (for the hour it is supposed to send the data), an ID and an indicator of the structure of the packet set. This is superficial when we send only one packet but in many cases the data won't fit only one and we'll have to send a whole set of packets. So for example each packet would have some bytes saying "sending data for time 16:52, packet # 4 of 23".

First shake

The modem sends the whole packet set to the server. The server hopefully recovers some of them. If the server received a non complete set (it would know thanks to the indicated structure of the packets that some are missing). Alternatively, if all the packets were lost, the server would know because it's supposed to receive some data on the hour given.

Second shake

The server sends to the modem information (also with UDP) which packets it did receive (or if if it received none) or the information it received them all.

Third shake

The modem hopefully receives the information from the server. If the information says some packets are missing, the modem returns to first shake and sends only the missing packets.

If the information says all packets were received, the modem sends server the third shake basically saying "ok, good to know."

Trigger points

Now what to do when when things don't go as planned.

If the information from the second shake says some packets are missing, the modem returns to first shake and sends only the missing packets.

If the modem didn't receive the feedback information from the server, it doesn't do anything (so all the dirty energy-consuming work is done by the server).

If the server sent feedback packet and maybe received some resent packets from the modem but after some time (for example 30-60 seconds) it's data is still incomplete or it didn't receive the third shake, it sends the second shake (the feedback info) again.

This way:

  • all of the data will be delivered eventually as long as packet loss probability is more than 0%
  • (almost) all the connection logic is handled by the server which saves on power usage of the modem
  • we open an equivalent of a TCP connection only for every hour-to-hour session, not every packet, which is probably much more energy efficient
  • these "connections" do not interfere with one another (thanks to the timestamps) so even if the conversation between the modem and the server takes more than 1 hour, still no data is lost.


Using UDP over TCP makes it a bigger concern that the devices can trust that they are talking to each other, not some other in-the-middle device which could for example send wrong packets to the server or send constant fake second handshake data to the modem.

Probably the simplest way to achieve this is use not exactly encryption but authentication using some simple digital signature so that each message is signed with the devices private key.

The process of checking the message against the RSA hash and the public key is not computationally very cheap, so that's another reason the server should sens to the modem as few messages as possible and rather receive them.

Of course you also go in and also encrypt the data sent.

Packet size

Worth noting is the fact that packets can't be quite big in size. The MTU for Quectel BC95 according to this data sheet is 512 bytes. We need to use 20 bytes for the IPv4 protocol, 8 bytes for the UDP which leaves us with 484 bytes for the actual data and also the timestamp, the packet set structure and the authentication/encryption hash.

So yeah, that's the way you work around UDP to work more like TCP.

  • Welcome to the forum, Jantek. Well organized answer. We'll see if the op tells us what they finally did, 3 years ago. Timed out on me when I tried 6 months ago ! Commented Jan 19, 2022 at 20:34
  • @kalyanswaroop Thanks. I saw it was a question from three years ago and there is very little chance to get feedback from the OP but I decided it's enough universal and important problem to have a good answer for the future readers. Commented Jan 20, 2022 at 8:04

I'm assuming you're already OK with losing some UDP messages on the internet. There are a few other issues you may want to consider:

  1. Will someone on the internet feed you bytes (probing) that may come in as junk
  2. Will someone deliberately feed bad data. (format matches, but bad numbers)
  3. Will this operator have trouble with UDP later, with TCP only OK?

If they at least allow HTTPS, you could put a certificate on your connect and only accept known devices at the server and solve 1, 2, 3.
If you are actually stuck with UDP, you have 3 as a risk.

To solve 1, send a message that has a blob with your data and a checksum. You could use nano protobuf for making the blob if you prefer that to JSON. So, at the server, you may know if it doesn't parse or if the checksum does not match, you can prevent 1 above.

To prevent 2 above also, you'll have to use a checksum that cannot be generated by someone else, such as a hash of your data, concatenated with a known secret, (and adding a salt for better protection), etc. Another option: encrypt what you send with a known secret. If you can decrypt it, it means 1 and 2 are both OK. Look at DTLS.

Now, you'll have to find a way to store those keys, make them, etc. And if someone in your org leaks the keys, its a big problem!
Also, see if you can allow only a certain IP range at the server. At least blocks some of the attacks. But given that you're using NB-IoT, maybe there's some way to do this well with the cellular provider. Ask them. Maybe, with that support from the cellular operator, you don't have the risk of 1, 2 above.
You'd be reinventing so much that's in CoAP otherwise!


the Quectel BC95 support the MQTT protocol and you can use MQTT to connect to the server I found this documentation about it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.