Make Applications discover each other via UDP [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
I want to make a application in C on Linux where there are multiple processes running on one computer, which come from the same binary. It is not exactly defined how many of these processes there will be (2-20). I want them to find all the other running instances of the binary when they start up. The processes should communicate over UDP with Linux Sockets and when one application sends a packet every process should receive it.
At the moment i have set up some basic udp message sending between two clients with fixed predefined ports. The goal ist to have them start up and get some port assigned from the os. The applications then should find other instances of the same binary and communicate with them. How can implement this sort of searching ? At first i tried to make them all listen to some fixed port via SO_REUSEADDR, but then just the last process to start up will receive all traffic. Then i looked into Multi and Broadcasting, but i think i need different ips for that to work.
Thanks in advance

Each instance of your application should create a socket that is bound to the same port. You'll need to set the SO_REUSEADDR on the socket before binding to allow this to happen.
As you've already found, when you have multiple UDP sockets bound to the same port and a unicast packet arrives only one of those sockets will receive the packet. To get around that you'll have to use multicast. If the sockets are all listening on a multicast address and a multicast packet it sent, all sockets will receive the packet. This also has the advantage of working whether or not the processes are on the same host.
After you set SO_REUSEADDR and bind the socket, you'll want to join a multicast group by setting the IP_ADD_MEMBERSHIP option. You can use any valid multicast address for this in the 225.0.0.0 - 239.255.255.255 range (avoid 232.x.x.x as that is for source specific multicast) and all instances of the app should join the same group.
You should also set the IP_MULTICAST_IF option to set the network interface for outgoing multicast packets, and if you want the app to receive multicast messages that it sent itself, you'll also want to set IP_MULTICAST_LOOP.

Related

UDP - Multi-server single client

I have a linux computer with a code in C that must communicate in UDP with 4 differents equipments. The computer sends differents commands to each equipment and receives responses, sometimes in parallel ...
I am a perfect beginner, and managed to communicate with one equipment using UDP socket. But now, i'm looking for a way to communicate with all these equipments, what i would like to call "multiple socket", but i don't know where to look/ what word to search to find a way ...
My linux computer is the client and all the equipment servers. I only have one eth port on the computer and will have to use a switch to have access to all the equipment. I would like to create functions like :
sendcmd(IPnumber, PORTnumber, cmd , ...)
readbuff(IPnumber, PORTnumber, buff, ...)
so i can choose which IP will received cmd ... i don't know if it's possible or if i need to open the socket, then close and redo the operation with another IP ...
So, if I ever managed to make myself understood, where should I look for a solution to my problem?
Thank you !
You can use a single UDP socket for your scenario. You can keep the socket open for the lifetime of your application.
UDP is not connection oriented. UDP sockets are also not classified into client sockets and server sockets. UDP sockets are always bound to a local port, either implicitly (typically for pure clients) or explicitly (which is usually the case for servers). In your case you do not care about the port for your UDP client.
To send to your four UDP server you can use sendto(). This lets you specify the destination IP address and port the UDP packet gets sent to.
To receive from your four UDP servers you can use recvfrom(). This will tell the IP address and port where the UDP packet came from.
You most likely want to have a receive loop of some kind. If you want to do anything else in your application you most likely want to either make recvfrom() non-blocking or you want to have the receive loop in its own thread. But this goes beyond your question.
The most important aspect of UDP is that it is not a protocol (despite its name which is misleading). It is one puzzle piece for a protocol. It is a tool to develop your own protocol. But I assume you already have a specific protocol at hand defined by your peripherals.

How to multicast to specific IP addresses?

I found a multicasting example at http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html that is simple enough. In our network, we intend to run the client app as a daemon on each of the machines. However, the server needs to multicast files only to specific clients at a time.
Is there a way to extend multicasting to specific IP addresses? If so, how do I extend the server code to do so?
Otherwise, I am thinking I will initially send a packet that contains the list of acceptable IPs. If the client sees that its IP is not on the list, it will simply ignore the packets that follow. This might work as I have complete control over the server and the client code. Is this a reasonable strategy?
If you know you're only sending to a single IP, it's just as easy for the server to send to an unicast IP address as it is to send to a multicast IP address. The socket on the client side that is set up to read multicast packets can also receive unicast packets sent to it directly.
It's a matter of setting the sin_addr field in the struct sockaddr_in you're using to pass to sendto(). So if 230.1.2.3 is your multicast address and 192.168.1.2 is the specific client you want to send to, instead of this:
addr.sin_addr.s_addr=inet_addr("230.1.2.3");
You do this:
addr.sin_addr.s_addr=inet_addr("192.168.1.2");
The method of having the payload of the multicast packet containing the list of acceptable IPs is also a good solution. This will allow you the flexibility to send to a subset of clients that are listening. Just make sure the packet has a well defined format. Having an application header that contains the number of IPs listed and/or the offset of the main payload is a good way to handle this.
EDIT:
If you want something off the shelf that can multicast files reliably, you can use an application I created called UFTP. It also has a unicast mode if you need that.

Chat server and client implementation? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I've been dying to implement a chat server in C and Winsock for a long time now, but I haven't taken the time. Partly, because I'm still unsure of some of the conceptual ideas about building a server on Windows OS'es for something like chat.
Here are some of the issues I've been thinking about :
How will user x connect to my server over a generic LAN
without me relying on them to type in a network address( e.g. address
could be invalid, redirected to a different server, etc. )
If I use broadcasting to solve the above problem, will that be reliable enough for chat?
Will that potentially DDos a LAN since the packets will be be forcibly handled on every machine and may take a lot of bandwidth if enough people join?
What is the difference between multicasting and broadcasting? Is multicasting truly superior?
Etc.
Per request, my definition of reliability would be that I can get most of the data consistently in sent packets. In other words, I don't mind a few dropped packets, but I do mind if the data gets messed up quite a lot along the way.
Currently, I have a lot more questions than answers, but the main point I'm getting at is this :
What is the safest and most reliable way of implementing a chat over a LAN in C and Winsock?
How will user x connect to my server over a generic LAN without me relying
on them to type in a network address( e.g. address could be
invalid, redirected to a different server, etc. )
Use a closed list of known servers, or use some broadcast based autodiscovery system.
If I use broadcasting to solve the above problem, will that be reliable
enough for chat?
Define your requirements for reliability.
Will that potentially DDos a LAN since the packets will be be forcibly
handled on every machine and may take a lot of bandwidth if enough
people join?
It's a chat... the amount of generated packets will be comparatively short and small.
What is the difference between multicasting and broadcasting? Is
multicasting truly superior?
Search the web. There are lots of resources and information about multicasting, most precisely, IP multicasting. In short:
Broadcast delivers to all hosts on a broadcast domain. Multicast delivers to all hosts that have explicity joined a multicast group, which may not be in the same broadcast domain (see last point).
Broadcast forces a switch to forward broadcast packets to all its interfaces. Intelligent switches can benefit from peeking at IGMP packets to know which interfaces multicast packets have to be forwarded to.
Broadcast cannot treepass a broadcast domain. Multicast packets can traverse a router, if it's configured to route multicast (search for M-bone)

When to use bind() when programming with sockets?

I am writing a simple sender and receiver program to transit using UDP so it's connectionless, but I am having a problem figuring out whether my receiver program needs to call bind() or the server and/or both. My receiver program(client) will sit in an infinite loop waiting to receive data from the sender(server) and then it will print out the data. I'm not quite sure what bind() does exactly besides associating an address/port with a specific socket. Why is it that I need to call bind()?
You need to call bind(2) so that the OS knows which application to route network packets to. When you call bind with a specific port for a given protocol (e.g. TCP or UDP), you're asking it "whenever you see a network packet on port XXXXX, please give it to me".
Say, for example, that two copies of your program were running, and they both wanted to listen for UDP packets on the same port. If they both call bind on the same port, then one will succeed and one will fail, since the OS can arbitrate who is bound to each port. Then, any packet received on that port will be given to whichever instance of the program succeeded at binding to that port.
when you want to make a socket a fixed address or/and port, you use bind.
See you when developing a Network Application you need to specify "Address and Port" to Bind because if you want to set it for Localhost your application is not able to communicate with the all over the network its only for your system which its communicating.. If you set it with your Network address it's not able to communicate as localhost Its only communicate with the network and If you set it to 0 then It can be use as both for localhost and Network.

How to bind a Raw Socket to a specific port?

I am currently working on a programming assignment. The assignment is to implement a client,network emulator, and server. The client passes packets to a network emulator, and the network emulator passes to the server. Vice-versa applies as well. The prerequisite for the assignment is that I may only use raw sockets. So I will create my own IP and UDP headers. I have tested my packets with wireshark. They are all correct and in the proper format(it reads them properly).
Another requirement is that the emulator, client and server all have specific ports they must be bound to. Now, I do not understand how to bind a raw socket to a specific port. All my raw sockets receive all traffic on the host address they are bound to. According to man pages, and everywhere else on the internet, including "Unix Network Programming" by Richard Stevens, this is how they are supposed to work. My teacher has not responded to any of my emails and I probably will not be able to ask him until Tuesday.I see two options in front of me. First I can use libpcap to filter from a specific device and then output to my raw socket. I feel this is way out of scope for our assignment though. Or I can filter them after I receive them from the socket. This apparently has a lot of overhead because all the packets are being copied/moved through the kernel. At least, that is my understanding(please feel free to correct me if i'm wrong).
So my question is:
Is their an option or something I can set for this? Where the raw socket will bind to a port? Have I missed something obvious?
Thank you for your time.
--
The man page for raw(7) says:
A raw socket can be bound to a specific local address using the bind(2) call. If it isn't bound all packets with the specified IP protocol are received. In addition a RAW socket can be bound to a specific network device using SO_BINDTODEVICE; see socket(7).
Edit: You cannot bind a raw socket to a specific port because "port" is a concept in TCP and UDP, not IP. Look at the header diagrams for those three protocols and it should become obvious: you are working at a lower level, where the concept of port is not known.
I would think you're expected to filter the packets in your software. It sounds like the exercise is to learn what the different components of the IP stack do by recreating a simplified piece of it in user space. Normally in the kernel, the IP code would process all packets, verify the IP headers, reassemble fragments, and check the protocol field. If the protocol field is 17 (udp), then it passes it to the UDP code (every UDP packet). It's up to the UDP code to then validate the UDP header and determine if any applications are interested in them based on the destination port.
I imagine your project is expected to more or less mimic this process. Obviously none of it will be as efficient as doing it in the kernel, but since the assignment is to write (part of) an IP stack in user-space, I'd guess efficiency isn't the point of the exercise.

Resources