I'm working on a socket project and now I'll make a UDP listener for server-side. I have looked some examples and I can't understand this; Why we have to bind UDP socket like "socket.Bind(new IPEndPoint(IPAddress.Any, 3000));"? Namely: in the TCP socket, we bind only our local ip but in UDP socket, we are binding IPAddress.Any. Why we are doing this?
EDIT: What are the wildcard and particular IP Adresses? How can we use them?
I found this and I think I was looking for it :)
The wildcard is a special local IP address. It usually means "any" and
can only be used for bind operations.
The value of this IP address is 0.0.0.0. If you have two network
adapters, one with IP address 1.1.1.1 and one with IP address 2.2.2.2,
then you can create a listening socket and bind it to 1.1.1.1 so that
the socket will not bind to 2.2.2.2. You can also create a listening
socket and bind it to 2.2.2.2, so that it will not bind to 1.1.1.1. If
you do not care and want your socket to bind to all network cards,
then you bind it to the wildcard address.
Another special value would be 127.0.0.1, meaning that only clients on
the same computer could connect to your server.
Link: What does wildcard address in InetSocketAddress mean?
You can bind both TCP and UDP sockets to either the wildcard address (INADDR_ANY or IN6ADDR_ANY_INIT) or to a specific address. There is no reason why you would typically bind a TCP socket to a specific IP address while you would bind a UDP socket to a wildcard address.
Related
I am trying to build a client server socket library that will abstract the complexities of sending and receiving data. I was wondering if you have a UDP server setup to have a multicast group. Can it still send and receive unicast requests to specific clients if needed? Or do you have to have to open two sockets to handle either type?
You can do multicast and unicast at the same time using the same socket.
You can send and receive any multicast and/or unicast UDP packets interleaved in anyway, so even if you want to talk to many different peers, some multicast, some unicast, you can use a single socket for this, and it fact it is often useful to do so in terms of complexity of the application.
Some things to consider:
On Linux you will want to bind() your UDP socket to your desired port and to the IP address 0.0.0.0 (INADDR_ANY). This will enable you to receive UDP packets targeted at any multicast address and any unicast address. Specifying a concrete IP address for bind() with UDP has a filtering effect and will only let UDP packets in targeted at that specific UDP address, which is rarely useful in practice, as all multicast servers usually also want to allow the same traffic to arrive as unicast, transparently.
On Windows binding to a fixed nonzero IP address has different semantics: It binds the UDP socket to a specific interface (the one with the given IP address). Sending and receiving UDP traffic for multicast/unicast should work on Windows even without binding to 0.0.0.0.
Good day all
I am going through the MSDN website try to familiarize mystelf with Multicasting and how it works. I'm wondering: when does one use the
IPAddress.Any
it refers to a commented out line from this link
//IPAddress localIP = IPAddress.Any;
I have seen it on multiple occasions, but what does IPAddress.Any really mean?
UPDATE
A quick googling reveals:
What's IPAddress.Any - MSDN Forums:
IPAddress.Any will listen on any IP Addresses assigned to the PC. For
example, if I am connected to the network via wireless and wired,
there would be two IP Addresses assigned. This means that I would
listen for requests on both IP Addresses. If I would take the IP of
say the wired then I could only receive requests from that NIC.
As you can see, this is for specifying an address to listen on (effectively, an equivalent to IPAddress.Parse("0.0.0.0")) and thus is not specific to multicasting. See How to do a UDP multicast across the local network in c#? for an example of the latter's implementation.
We're using Fleck for our Websockets.
When we test our network program locally it all works fine. The process of a client connecting is:
Establish TCP connection
Send/receive infrequent TCP messages
Start sending/receiving UDP stream to server
The problem is on the live server which is far away geographically, clients can receive and send TCP messages, and they can send UDP messages, but they do not receive UDP messages.
We've investigated it as far as we can, and have found that the RemoteEndPoint property of the TCP connection on the server has the wrong IP address. It appears to be an IP address from our ISP. We use this IP address to attempt to send UDP messages back to the client. As it has the wrong IP, the client never receives these UDP messages.
The actual source IP address of the client must be known somewhere, as the TCP messages make it back OK. I've gone through the Fleck source and have printed out the RemoteEndPoint of the underlying System.Net.Socket but it keeps giving the wrong IP address.
Does anyone know what is going wrong and how we can expose the actual IP addresses of the clients?
The most likely reason is that your client does not have a public IP address, but a private address behind Network Address Translation (a very common setup). A common private addresses are of the form 10.X.X.X or 192.168.X.X.
NAT device replaces private address in a packet from your client with its IP address, which is public. For the outside world it seems that the traffic originates from the NAT device. The main advantage of NAT is that it allows many clients to use a single public IP address (IP addresses are sparse). But NAT introduces a problem: an incoming packet needs to be routed to a correct client, but it does not have a client IP address. Some other strategy needs to be used to recognize to which client a packet should be routed and such routing is not always possible.
For example, the most well known limitation of NAT is that you can't simply start a listening TCP server behind a NAT and then connect to it from the outside world. The reason is that NAT device has no idea that your server listens on a given port and thus, it has no way to known that TCP SYN packets from the outside world need to be passed to your client. A workaround for this is to explicitly configure the NAT device to route SYN packets directed to a given port to a specific client (port forwarding).
When a client behind a NAT initiates a TCP connection, a NAT device remembers state of the connection (client address, client port, remote address, remote port). Because of this, when a response arrives, the device knows to which client the response should be passed. When the connection is closed, the device discards state information. This is why your client can communicate over TCP.
But UDP is more difficult to handle because it is connectionless and stateless. When the device sees a UDP packet it does now known if a reply is expected and when, so not all NAT devices handle UDP traffic. Although there is a technique that allows to do it.
To summarize: the problem you are seeing is not C# specific. Setting IP address in packets from your server to the client IP address won't help, because it is most likely a private address that is not routable. To solve the problem you need to use a NAT device that can pass UDP traffic in both directions. But if you are developing a generic client to be used in many setups, you may want to reconsider if UDP is the best option. TCP connection forwarding is a basic feature that all NAT devices support, but some devices may not support UDP.
I am testing my socket programs at home, in local network.
Server and client programs are running on seperate machines.
Server program socket is binded as: serverSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8999));
Client program (on the other computer) is connected as: clientSocket.Connect(IPAddress.Parse("192.168.2.3"), 8999);
Why can Client not communicate with server?
Do I need to make some firewall configuration or something like that?
Or am I writing Server Ip incorrectly to the Client? (I got it from cmd->ipconfig of server)
You are only binding to local 127.0.0.1 IP therefore your server would be accessible only from the same machine. Try the following:
serverSocket.Bind(new IPEndPoint(IPAddress.Any), 8999));
Because your server is binding to the localhost loop-back address 127.0.0.1. This means nothing except what's running on the server can communicate with the socket.
You need to:
verify the server has a network connection on the same subnet as the client (192.168.2.0 or 192.168.0.0) - call it the "public" IP address
bind your socket to the server's "public" IP address or bind your socket to all interfaces - usually with the special IP address 0.0.0.0
We have a simple piece of legacy software with which we need to
communicate using TCP/IP over port 15001. We need to listen on port 15001
for the legacy software to make a connection and then read whatever it sends us.
We have tested this solution accross the internet and it works just fine.
If however we test the same solution across a GPRS TCP/IP network it does not.
All the basics have been checked, we can ping other devices in the GPRS network
and port 15001 is not blocked by any firewall.
So maybe there is something wrong with my TcpListener?
It is initialized like this:
tcpServer = new TcpListener(IPAddress.Any, TCP_PORT);
I'm assuming it listens on every available IPv4 enabled interface on the system,
because I used IPAddress.Any ?
Does anybody have any idea what the difference might be between the two networks? (Even though there shouldn't be any difference) and if there is something I need to change to my TcpListener?
You need to specify the IP address on which you want to listen, instead of IPAddress.Any. See here. When you use IPAddress.Any, it will automatically choose the network interface for you. To listen on a certain interface (in your case, GPRS) you have to use the correct IP in the constructor.
This post has more information on getting the IP address for each nic.
Also, if you're looking to listen on every IP address at once, you'll need a TcpListener for each nic.