learn network programming in c, but without all those pesky sockets
Вставка
- Опубліковано 8 лют 2025
- When learning to program, one of the first advanced projects you'll get is a networking project. You may even have this in your classes right now where you need to send data from a client to a server and vice versa. This isn't an easy task for a new programmer, and while you should definitely learn the C networking API for Linux or Windows, there's an easier way to do this.
ZeroMQ or ZMQ is a message queue library that provides an abstraction over the socket API to make networking easier in C, as well as many other languages. In this video, we go over a basic implementation of the ZMQ library, using a request response schema for a basic networking application.
ZMQ API: api.zeromq.org/
🏫 COURSES 🏫
www.udemy.com/...
🔥🔥🔥 SOCIALS 🔥🔥🔥
Low Level Merch!: www.linktr.ee/...
Follow me on Twitter: / lowleveltweets
Follow me on Twitch: / lowlevellearning
Join me on Discord!: / discord
Leave a comment, let me know what YOUR favorite networking library is!
Python 😁
bruh you use libraries
zmq is the best library, this lib has so many usefull patterns such as PUB SUB, ROUTER DEALER, etc..! I love it.!!!!
I used to use MPICH all the time on a Beowulf cluster.
x86 assembly
What’s wrong with the linux sockets API? It’s actually very logical and clean, I don’t understand how this is any better.
Hello, zmq has a bunch of patterns such as PUSH PULL, ROUTER DEALER. This lib is awesome.
This here didn’t seem as good as the normal socket libraries. Maybe it has lots of advanced features that weren’t shown but it didn’t seem any better.
I agree, just normal plain sockets looks just as good as this.
plain sockets are fine but you have to take care of lot of things yourself like handling partial messages, in UDP reassembling and reordering packets and so on.
however there are many alternatives to zeromq which are less bloat, furthermore zeromq is written in C++.
Thanks! I knew about 0mq solving pub sub problem.. ok… but NOBODY ever said it’s also easier. Now I have a fresh compelling reason to check it out .
Awesome video, that PTSD from the socket API got me looking for alternatives. Thank you very much!
I have been using ZMQ for awhile now to build distributed computing software for Manufacturing and Execution Systems and it works really great... can do anything from normal pub sub and req resp patterns to esoteric patterns like radio dish and multi stage compute pipelines. Maybe someday someone can show it working on an ESP32 or similar...
i wish i was smart enough to understand ZMQ :(
Before investing your time in 0MQ, here are a few considerations:
* The sockets API is well documented, and underlies all IP based networking software. You'll need to learn it sooner or later.
* 0MQ is not a replacement for the sockets API; rather, 0MQ is a pub/sub networking toolkit built on top of the sockets API.
* NATS is a similar pub/sub toolkit which is widely used in industry, but with better intrinsic security than OMQ.
* If you want to write networking software which is as reliable as possible, you will need to learn how to use non-blocking I/O with a single thread. 0MQ (and NATS) kick this can down the road by using seperate threads under the hood to buffer messages.
"you will need to learn how to use non-blocking I/O with a single thread" why not use non-blocking I/O on multiple threads
@@mihailmojsoski4202 nothing against learning to do that; I do this myself when I must. Multi thread programming is often a tar pit full of bugs which are very difficult to find, and may manifest differently depending on the number of CPU cores.. For many applications programs, a single thread + non-blocking I/O can easily saturate the system's network I/O capability.
This is sweet. Sockets is fine but I'm already bangin away at some crazy stuff with this API. Thanks L3!
What I like about sockets are the IO Strategy, especially multiplexing, to handle multiple sockets, using select option to select only the sockets that has pending data, and IOCTL where you can check the state of a socket or set a block state to a socket.
For socket strategy there is IOStrategy, Async and Multi-threaded,
- IO strategy uses a single thread where it selects sockets that have pending data to handle them,
- Async uses opens and closes or uses a thread-pool to handle sockets in separate threads, if you have to synchronize data received from the sockets you have to synchronize it manually
- Multi-threaded handles sockets in separate threads, in my opinion multi-threaded should be avoided, it is the easiest to handle but the slowest when handling a lot of clients,
- There is also an hybrid mode where using IO Strategy in separate threads as socket channels, for example
I also wrote 3 layers of abstraction for the socket library in c++, Socket->DataSocket ->Listening and Connection socket, after this I wrote the communication protocol, because send and recv, does not ensure, you will receive the full message, because if the message is too big, it will be broken into chunks or receive part of the next message, especially if you have blocking turned off per socket
A good socket library should have options to use their own strategy(IOStrategy, Async, Multi-threaded, etc,) to handle sockets, an easy to use listening and connection socket, also a communication protocol,
a week ago i had no experience in c and 2 days later i made a web server hosting a simple api using winsock2 thanks to discovering this channel! i really enjoy your c videos especially!
It would been 2 hours if you used python lol
@@billigerfusel python saves dev time, C saves user time
@@billigerfusel more like 2 minutes lmao
@@billigerfusel With no prior experience, I really doubt..
Python is too abstract to make sense imo
I tried to use zmq once in the project, but realized that it does not guarantee delivery on its own. I read parts of zmq source and it appears to me that data, which was sent from zmq and is then in OS network buffer, may get lost when TCP connection will break. Zmq will do re-connection for you, but data from OS buffer may never get to the destination. So without implementing some acknowledge protocol over zmq messages I could not be sure that data put to zmq will be actually delivered. I tried to do that and it was like re-implementing TCP in simplified form. Another solution I came up was to listen to socket events (or whatever it was called) and reacting on disconnections in some way.
It's nice but so basic. Maybe the rest of the library is more advanced, like for example handle multiple streams concurrently (have a context for the underlying socket) or asynchronous networking like select/epoll.
Your reading comprehension is the only thing that's basic here.
@@waytospergtherebro how does it feel to be mean?
@@waytospergtherebro go shag a cactus 🌵
@@waytospergtherebro no idea where that came from, are you okay?
Most people who have used sockets would look at this example and think what is the point of that, since this library doesn’t seem to have any benefits over just using sockets. This is a very basic example however and doesn’t show off any advanced features.
THANKS for this video, im looking this kind of video for ages
I love this video. Thank you so much. Now i want MORE SOCKET RELATED PROJECTS
Awesome! Looks promising for embedded devs.
Hi, wouldn't the zsock_destroy function in server.c never be called ? Wouldn't it be better to setup a function whenever a SIGINT is received that destroys the socket and terminate the server ?
Better idea
From the documentation for zstr_recv: Returns NULL if the context is being terminated or the process was interrupted.
Maybe check for NULL and leave the loop?
Happy 100k subs!!!
Thanks!!
Thanks man, awesome vid.
I've just started to use this library to deploy C code directly to a Raspberry Pi robot of mine.
it's super useful. Keep Rocking \m/
I used ~5 years ago zmq for a RADAR-System to transmit processed I/Q-Data to a websocket-server. From there on, the clients received the data via websockets inside the provided web application.
Similar application here, I found 0MQ in GNURadio so I used it there.
Interesting how zmq have stuff running post main to detect non freed resources. Maybe that's a signal handler or something, will grep for dangling in the source when I have an opportunity. Thanks for the video!
In my day job (sadly) I do a lot of web development... this seems very familiar. Nice.
Is GO a good choice for network programming?
@@LeoWasHere1 Yes, it's used a ton in the field.
at first looking at the title I thought this man was gonna interface the network card directly
This got my attention 😮😮
It would be nice a Demo using libcurl library and then integrates with a json parser library 😉. Great video 🙏
0:40 shrek in the top left corner
If you're doing networking in C to learn C, this is good, if you're doing networking in C to learn networking, better use the socket API to handle all the networking yourself and understand it more
thank you for your video, I am writing a game wih the SDL. it need to use socket, linux api doesn't work on windows, SDL_net.h also hard to use. but I fond you, it is a new way to use it.
Do you have / are you going to make a video on the Linux Sockets API?
Thanks. Maybe someday it’d be great to do the same thing in sockets, revisit 0mq at the same time… sort of a compare and contrast.
Bro, thanks you!
This is messaging middle-ware and not network programming. They are different users completely. And not just an abstraction.
Also the TCP/IP network programming API is from UNIX not Linux.
Can you please make a full tutorial on making a C http server for beginners
that's cool, but what about performance tradeoff?
Isn't the socket freed by the OS when a process dies? I always thought it's just a good practice to clean everything, but not strictly needed
Nahh, I’ll just stick to sockets, plus it’s not doing a lot of abstraction, still bind and connect, what if u wanna use UDP instead of TCP !! though I really loved the way how it giving a warning about the not freed socket.
0:06 I do actually have a C networking assisgnment right now :D
cool but what if we need to serve 1000 clients asynchronously? maybe io_uring (liburing) will help?
I've heard of ZeroMQ but not CZMQ. Is it like a more simplified version?
As for my favorite net lib? In C, I'm using the sockets API directly, with Winsock startup/shutdown boilerplate, because I need like raw TCP/UDP a lot of the time. I want to use Rust, but that's where networking gets... complicated, especially with concurrency, which I'm also struggling with, though the channel semantics look promising. The `tokio` crate seems like the go-to, but if you need a program to do expensive calculations as well (ie. a server-side authority game server), that's where it falls short. I was told to use std::net in conjunction with the `rayon` crate in such cases, but concurrency and networking on that scale makes brain soup.
Looks like someone reinvented the wheel. This is the same thing as the sockets API but less powerful. Was that the goal ?
Spent all day trying to compile ZeroMQ in Visual Studio 2019 with its C++ binding. Learned I've to move on and find something else. Maybe I can compile its C binding on Linux and use the generated library back on Visual Studio (Windows)? Don't want to lose more hours. Also, couldn't find an understandable example of how to implement async named pipes on Windows with C++.
If you are running it for sometimes,
A client sends a request then crash,
Rerunning the client may have a sync issue! How to deal with that situation? A server is sending a message but no client to read, and the new client is sending a message server is busy
👍Thanks.
Have you heard about DDS?
I wish you do a series solving 42 networks school exercises.
Why didn't localhost work on the server side?
Nice.
Very nice
> networking in c but without all those pesky sockets
> so we're going to be using zsock
it do be like that
I was HUGE ZMQ fan, but I don't think it's grown as much after the passing of Hintjens, their BDFL.
I once re-architected the provisioning system for a cloud backend with ZeroMQ and it was such a perfect fit for a distributed, lock-free concurrency across global data centers.
My biggest reason to not use ZeroMQ nowadays is a relative lack of security standards across bindings/libraries, particularly for authN and encryption. It also has relatively weak support for some programming languages, like JavaScript.
Still, what's better than zeroMQ for building distributed systems? Nothing as far as I am aware 😅
I may someday make my own ZeroMQ alternative, it's just so much work 🥹. It would have to be written in Rust! 🤣🦀
> what's better than zeroMQ for building distributed systems?
Erlang?
I think there's a newer one called nanomsg but I haven't used it
@@rabbitcreative the language of 9s!
Zeromq rocks
LocalHorse Gang checking in here
Didn’t you need to allocate a number of bytes for the returned msg string? You just have char *msg in the server and char *str in the client without allocation. Maybe I’m looking too far into this quick demo but just curious as welll.
The receiver allocates it for you :)
very rarely people talk about zeromq
> networking is not hard
it's hard when you get out of ping-pong client-server code. multiple client support (read - threading), buffered reading, all kinds of security things and wrapping your data inside of it - thats when things start to get hairy, and raw sockets, binding and stuff ain't actually the scariest part at this point.
Ah yes, all those pesky functions that do the exact thing I want them to.
To any students watching: Learn the damn socket api. Don't use this crap.
Save higher level abstraction until you learn and understand what happens under the hood.
8:18 it's not C if there isn't at least one segfault
Not sure I learn that much by using a library?
ØMQ is a facade then? It kinda sounds like a Plan9 channel.
I wish i was smarter so I could understand ZMQ :(
Isn't this video the opposite of what this channel is supossed to do?
You forgot an exit after your bind check. Now it will still go into the loop.
Ugh the receive call returns a pointer to data?! That is a daft implementation. You would want to pass a point to a data block, Because now you need to free the pointer to the data after everything call.
Otherwise when you pass in a data pointer you would just free it after your client is done. This returning of a data pointer is not very C-like.
so you'd rather have either a buffer overflow exploit or require many lines of boilerplate code instead of being not C-like?
@@KingJellyfishII I don’t think you see the incredible danger here.
As this is a memory leak waiting to happen!
And you don’t get a buffer overflow by pre defining a buffer and telling read() how many bytes to receive. It will never return more than specified, that’s the whole purpose of telling the number of bytes to read in the first place.
Actually this also is a great way to get a memory overflow and cripple a whole system, because a server can create a stream that’s infinitely long and the way I see it, this receive call will most just realloc and keep growing the buffer until memory is exhausted. Otherwise how does the user know it only got a partial packet?? Nothing is telling you that here.
So this in any case this library is worse (and just not good C practice) than predefining a buffer, that you have full control over and will never overrun if you out the right size in read(). And you can manage large streams without running out of memory when you do it yourself.
And I wrote my own wrappers ages ago to handle all this, so I dealt with the boiler plate ones.
Take it from someone who’s been developing client server applications since 1997.
@@CallousCoder Thanks for your detailed response. I think my annoyance comes from constantly having to implement a resizable buffer using realloc for some annoying protocol that uses essentially null termination of packets (that are required to be ASCII). However, i realise that most protocols are probably less annoying than that.
@@KingJellyfishII yeah I feel you, been there done that once.
Because you need need to then know when to stop reading. Most protocols actually put a size in the header or message are fixed size. That’s generally how protocol design is done. And in case of streams (like a get from ftp - although that also knows the size) you just immediately push to disk after each read(). But if you have preconceived notion on how much you are going to receive than its really annoying and you will need to realloc then - it buffer to disk and read afterwards 😝
Maybe once you learn English you can put all that nonsense into a coherent sentence.
Nice video but It reminds me why I don't like programming in C for networking. Header files, **, * &, free etc
why would anyone need some library in network programing. I don't like it.
cool
Remove `sleep(1);`
128 comments, now 129
Bro is asking to get hacked.
onion.
Localhorse..
without sockets, but using socket lib. clickbating
and that's why I don't like c. global namespace everything.
Tenth view.
you need to shift your video back a little the slight audio desync is fucking killing me
Dude doesn't know what Ø is
Does this shit work on Zig too?
I sure love binding to tcp://localhorse:5555
You aren't checking that zsock_new isn't returning NULL.