Is it possible to bind and listen to one IP address with TCP/IP sockets? (Linux/C) - c++

I have always used:
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
which means that I will accept connections from any interface. If I replace the INADDR_ANY with “192.168.0.1”. Does this mean I will only accept connections from the IP address of 192.168.0.1, or does it mean I will accept connections from the interface of 192.168.0.1 resides on?
I have a situation now where I have multiple clients (each with a unique IP address but same port number), trying to connect to one server. Can I have multiple listens functions (separate threads) listening to a unique IP address and port? Or do I have to accept any connection and get the network information after I've connected?
Edit To give more clarification.
If I say serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1") and a client with IP address 192.168.0.2 tries to connect, will the listen command reject this?

The bind address is the local address to listen on; you can specify the address of a local interface.
If you want to control who can connect, you can either inspect the peer address inside the select/accept loop, or limit inbound connections using iptables.
Update
If I say serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1") and a
client with IP address 192.168.0.2 tries to connect, will the listen
command reject this? I want to be able to have multiple thread, each
servicing a unique IP address.
No, the address is an address on a local machine. Given that you're going for a multi-threaded design, I'd recommend you run the listen/accept code in one thread, check the client address, decide what worker thread is appropriate, and then spawn it.
At the risk of showing my age, I still prefer using listen/accept/select for most socket code - it's a personal taste thing, and yes, does influence the design when it comes to blocking/non-blocking IO, buffering, etc.

If I replace the INADDR_ANY with “192.168.0.1”. Does this mean I will
only accept connections from the IP address of 192.168.0.1, or does it
mean I will accept connections from the interface of 192.168.0.1
resides on?
Yes
I have a situation now where I have multiple clients (each with a
unique IP address but same port number), trying to connect to one
server. Can I have multiple listens functions (separate threads)
listening to a unique IP address and port? Or do I have to accept any
connection and get the network information after I've connected?
Yes. You can "fork" (i.e. create a new thread) for each connection you wish to process, however you'd have to do the filtering yourself. There is no way (that I know off in the API) to offload that work to the stack.

Related

How to make a .cpp file to act as an accessible server

I have written a simple program with Linux (Cent OS 7.0) and C++. It is a very small server which sends back a string of characters to the client. But my problem is that I don't know how should I access that server using an IP address?
I have used Linux Socket Interface (Berkeley), and in the section which defines the address, my code does the following:
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.
s_addr = htonl(INADDR_ANY);
serverObject.
sin_port = htonl(portNumber);
I use INADDR_ANY as my server's address which is defined in its definition as:
/* Address to accept any incoming messages. */
Now, how should I run the server, and then use my simple client program to send request to it. My simple client program accepts an IP address as it's destination address, this address should be the one destined toward to the server. How should I relate it then?
INADDR_ANY goes to specify that all active network interfaces in the system should be bound to. So if you're connected to more than one network, you'll be able to communicate with connections coming in from all of them. Most systems will usually have just one, though, and this still goes to say that if the IP bound to that interface happens to change, you'll still bind to that interface.
So, once you specify INADDR_ANY, you need to initiate connections according to the following rules:
If you're connecting from the same physical machine, the easiest thing would be to use the loopback interface (127.0.0.1). However, you can still do (2).
If you're connecting from another machine, you need to pick the accessible IP address of your server from that machine. As said above, if your server is only connected to one network, this will simply be the IP address of the server. Within an internal network this will often be something like 192.168.x.y, or 10.0.x.y—but it doesn't have to.
If you're connecting from a different network which uses a gateway to access your server, then you will need to set up port forwarding in the relevant routers so that when they receive connection to port X, they will know to internally transfer it to your server.
As a server programmer, you decide the port on which to listen, but not the address.
The internet address is provided by your internet provider, or 127.0.0.1 to test on your own machine.
There are plenty of web pages on internet that provide tools to tell you your current public address (search for What is my Ip).
Most of the "home" internet routers implement NAT: they have a single internet address and map them to many device, that carry the Port number to be changed (your port 80 become port (e.g.) 2345 for outside). To allows a client from outside your home to access your server, you are required to configure your router to map the server port, so for example your public port 80 map to your server port 80.
With that said, you should be able to connect your client to your server through an address and port.
If then you want to use a name (example.org) instead of an IP (93.184.216.34), a Domain Name Server is used. But that is another topic.

C++ Sockets with Router

I'm making a multiplayer game using sockets and I have some problems with the server side.The server shall be run from my computer which is behind a router. Therefore I'm a little bit stuck with what should the server inet_addr be. I am using port 1234 and I forwarded it to my PC ( the place where I keep the server ).
I have tried using my own ip address which i got from myipaddress.com, also my computer's router address ( 192.168.0.101 ). The first try i was getting A LOT of connections which ended up in killing the program and in the second try nothing connects to it.
addr.sin_addr.s_addr= inet_addr("192.168.0.101");
addr.sin_port = htons(1234);
addr.sin_family = AF_INET;
What should I do in order to make any client be able to connect to the server and the server to run from behind the router ?
With port forwarding in your router, the router needs to know which device to send packets directed at the selected port range to. The router is asking for your internal IP address, (websites only see your external IP address).
You can find this on Windows by calling ipconfig in cmd (I believe the command may be ifconfig -a on Linux), this lists all of your network interfaces and your internal IP address on any that are connected. You should look for a value in the form 192.168.0.xxx.
When someone then wants to connect to your server if you give them your external IP address and desired port, their packet will be sent to your router on that port, and it will forward it to your computer at the internal IP address.
If you disconnect your computer from the network regularly you may need to configure your internal IP so that it is static and always allocated the same address.
This has nothing to do with your program, and everything to do with your network configuration. Go learn about NAT (network address translation) and doing port forwarding or DMZ on your router.
Usually you want your program to bind to all interfaces - INADDR_ANY - but the important one is the address on the network controlled by your router (often 192.168.0.0/16, but it can be any RFC1918 address block).
Once you have your network configured on your router and binding the external interface from your program (don't hard code an address like in your example, just use INADDR_ANY)
serv_addr.sin_addr.s_addr = inet_addr(INADDR_ANY);

Any ip and local ip binding?

I'm working on a network platform that creates a basic I/O interface for make something fast/easy. I need to understand this, what is the main differences between binding any ip or local ip to socket? Why I need to bind local ip, why I need to bind any ip? Simple but important question :)
Binding a server socket to a local ip instead of to 0.0.0.0 can act like a poor man's firewall if you want to have a server that is not open to the entire world, but only to a specific group.
For example:
- You can bind a socket to the local ip if you want it to be used a way for different processes in the same machine to communicate.
- You can bind a socket to an ip if you want all access to it to occur through some external load balancer.
Remember that a TCP connection is made up of four things: Source address, source port number, destination address and destination port number.
When e.g. a server program binds a socket to a local address, two of those things are provided, and allows clients to connect to a well know destination.
When you bind to any address, it doesn't actually bind to any address, it just creates the binding for all local addresses. (For hosts that have multiple interfaces, which all hosts have.)

Boost-asio listening to multiple IP Addresses on a single (TCP) acceptor

A boost TCP acceptor can be wired up by using an endpoint constructor that only takes a port number as it's argument, in which case it will listen to all IP addresses/NIC's.
Is it possible to get the acceptor to listen to select IP addresses ? Or will I have to create an acceptor for each IP address I am interested in ? Looking through the documentation I couldn't find any indications of this being a possibility.
I haven't looked at the socket API for a few years, but I guess the API doesn't directly allow this.
there's unbound listening and bound one. unbound means you listen to all NICs, bound - to specific one. There's no possibility to select some of NICs, I think because the same can be achived by dedicated acceptors for each of them

Hold a network connection although IP address change

Is it possible to hold an open TCP connection with a client, while the IP address of the client is externally changed?
For example, the connection is establishes against address X, but somewhen while the connection is open, the client-side user asks for IP renew and gets another IP address. Can the connection remains alive in this case?
Thanks in advance.
No, it cannot.
Even if the local side could be massaged to understand that the connection is suddenly between different addresses, the remote side will not understand and will refuse to work with it.
You'd need to re-add the old IP address to continue using the connection.
To do so:
Linux: ip addr add 172.16.10.20/22 dev bond0
Windows: do some pointy-clicky or**fill in command here**
This is possibe with tcp v6 connections, if you're using e.g. tunnelbrocker.net. Every time your IPv4 address changes, the connection between your IP4 address and the tunnelbrocker's IP4 address is dropped then re-established, however your IP6 attress is the same and all the TCP/IPv6 conections from your IP6 address to your destination IP6 addresses are still here.
Or, if you're designinng both your client & server, your could design your protocol allowing the client to reconnect in a transparent way..
What I know is, when using UDP, the connection can be remained, one of my application is to change a remote network adapter address via UDP.
For TCP, I agree with Soonts, you should design your server and client application to allow the reconnect in a transparent way.