Reputation: 2127
I am stuck in the following situation: I have 2 written programs server.c
and client.c
. What these 2 aim to do at the end is to simulate a chatting app, similar to the one found in Beej's guide (section 6.2, page 34). However, I do something different. In my case the server just accepts new connections (with TCP) and whenever a new client connects/disconnects the server will send a message to all the other still connected clients and notify them. Again, the clients are connected to the server by TCP.
The server doesn't receive the clients' messages to then send them to all the other clients. No. In my case, what I want to do is have the clients communicate directly, without the messages first going to the server. I want to do this by using UDP broadcast in each of the clients. So basically, once a client connects to the server that client is done communicating with the server until it will decide to disconnect. Until then this client will only be able to send UDP broadcast messages or receive UDP broadcast messages, without interacting with the server.
The problem I have is that I don't have a port to use in the client.c
code. I can set the sin_family
to AF_INET
, I can set the IP address to the broadcast LAN address (ending in 255
), but I cannot set a port when creating the broadcast struct sockaddr_in
in the client.c
code. You see, I am running multiple instances of this program client.c
on my machine. I should be able to do this because the server is on my machine and the client is on a virtual machine so I can run multiple instances of client.c
in parallel since even tough they will have the same IP address, they will have different ports.
But I can't bind()
the broadcast socket to a port in the client.c
code. It will bind on the first run of my program, but at the second run it will see that the port is used and it will throw an error. Even if this would've worked, somewhere in the program I need to send a message using the sendto()
command and here I have to specify where I want to send it. Now there is no way around knowing the port. But I cannot know it, since each run of the program will have a different port unless I choose one and bind it. But I cannot choose one either, since in that case I won't be able to run multiple instances of the program because the second run would result in an error.
Is there a way to get around this? A way to send a broadcast message in the LAN without needing to bind to a port. And this should be done in such a way that other clients can see what was sent through broadcast in the LAN while also not knowing the port from which the message was sent. I know I can use select
to both read and write at the same time, but I can't get to the stage where I select since I can't assign ports to my clients. So I didn't get there yet. It basically comes down to having multiple clients, and these clients can send UDP broadcast messages and receive UDP broadcast messages at the same time, without having a server to orchestrate them. The problem is these clients have no port to work with.
Upvotes: 0
Views: 531
Reputation: 73294
You can bind()
multiple UDP sockets to the same port as long as you set the SO_REUSEADDR
and (under OS's that support it) SO_REUSEPORT
options on the socket first:
int fd = socket(AF_INET, SOCK_DGRAM, 0);
const int trueValue = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(trueValue));
#ifdef __APPLE__
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &trueValue, sizeof(trueValue));
#endif
// then go on to bind() the socket, using the same (fixed) port number for every client
Once you have this done you can create multiple clients on the same host (e.g. for testing) and they will all receive each others' broadcast-packets (and IIRC also they will also receive the broadcast-packets they sent themselves, so be ready for that).
Side note: if your plan is to have clients communicating with each other directly and never interacting with the server, then you might as well get rid of the server as it doesn't sound like you need it for anything(?)
Upvotes: 1