Sockets C# and different subnets - c#

I'm trying to implement a socket application for my very frist time.
WHen I use:
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
the localEndPoint IPEndPoint contains "192.168.56.1", that is my address under my VirtualBox network.
It should contain my local network ip ("192.168.1.165").
How can I manage it?
I looked over Google but I could find an answer sorry...

Your virtual machine doesn't know anything about the network interfaces in the outside world. You can only find out your local addresses with the NetworkInterface.GetAllNetworkInterfaces() method (see here). Anything else should be a configuration setting.

Use IPAddress.Any to simply bind on all local interfaces. You do not need to find out a specific local IP for most scenarios.
Note, that you are throwing away all but one address. No wonder that you are only getting one.
There is no such thing as the local IP. It is a set.

Related

Index was outside the bounds of the array at socket client c# code

I am using server and client sockets communication provided from (server, client). When I running those projects from the same machine everything is working fine. When I tried to use other pc as a client I am receiving the following exception message:
Index was outside the vounds of the array at asynchronousClient.StartClient() in line 47 which in fact is the second line:
IPHostEntry ipHostInfo = Dns.GetHostEntry("serverIp");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
EDIT IPHostEntry contains the name of the PC where server is stored. However ipAdress is null.
The error is raised because ipAdress is empty. The most likely cause for this is that the hostname exists (DNS knows about the domain), however, no A records exists. For clarification, the A in A record stands for Address and this record is used to find the address of a computer connected to the internet from a name.
From the documentation of Dns.GetHostEntry:
IPv6 addresses are filtered from the results of the GetHostEntry method if the local computer does not have IPv6 installed. As a result, it is possible to get back an empty IPHostEntry instance if only IPv6 results where available for the hostNameOrAddress.parameter.
Meaning, you only got back IPv6 records, and the method filtered them for you.

Comparison of C# Socket Implementation

I have been looking over socket implementation and ran across a few ways of implementing them.
However I am confused as to why some examples create extra variables to accomplish the same task.
IPHostEntry ipHost = Dns.GetHostEntry("");
IPAddress ipAddr = ipHost.AddressList[0];
ServerSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ServerSocket.Connect(hostName, 56);
I managed to get the above code collapsed down into two lines. Other than the ability to enumerate IP Addresses, is there another benefit to the code above?
ServerSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
ServerSocket.Connect(hostName, 56);
Thank you in advance for your help.
The intention of the first snippet is to automatically choose between IPv4 and IPv6. The first snippet probably has a bug. If there are multiple adapters (which is normal) an arbitrary address family will be chosen. Maybe IPv6 will be chosen and the connection will fail because the target of the connect call does not support IPv4.
Use the second version.
Also, this difference is not about "variables". It is about different semantics. You can arrange the variables as you see fit.
The:
IPHostEntry ipHost = Dns.GetHostEntry("");
IPAddress ipAddr = ipHost.AddressList[0];
is giving you your local Ip address. Well to clarify.. it is giving you the first one.
see Dns.GetHostEntry()
The GetHostEntry method queries a DNS server for the IP address that is associated with a host name or IP address.
When an empty string is passed as the host name, this method returns the IPv4 addresses of the local host.
The reason for the AddressList[0] is because a machine may have multiple local Ip addresses.

SocketException Connection failed

I use the sample code on MSDN but it cannot work.
Below is code:
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[2];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ipEndPoint);
You will need to also have an Active TcpListener on your local machine (i'm guessing by using Dns.GetHostname()).
Instead of relying on DNS when trying to connect back to yourself, you can use IPAddress.Loopback
The code that MSDN provided is for example. This means it may not work in all circumstances.
The problem you facing is, that there is no software listening on the port 11000. (for a client to connect on a port, there should be a server listening.) irl same like: If you (client) phone your friend, but your friend(server) isn't home(listening) to pick up the homephone, there will be no conversation. ;-)

SocketException on TcpListener.Start()

I'm trying to make a basic client/server program, but when I start the TcpListener it gives me SocketException:The requested address is not valid in its context.
I actually have a method that returns my public IP, and it matches ipconfig results, so the IP address string below can't be the problem. Of course, the IP shown below isn't my real IP for security reasons. I opened the port below for general use.
Anyway, Not valid in context is vague, so I'm not sure what that means.
Here's my code (for the TcpListener):
ServerIn = new TcpListener(IpAddress.Parse("100.100.100.100"), 8000);
ServerIn.Start();
Thanks in advance.
The TcpListener can only be bound to a local IP Address of the computer that runs it. So the IP you're specifying isn't an IP of the local machine. Your public IP isn't the same IP as your local machine, especially if you're using some kind of NAT.
If I recall correctly, it's common to just do IPAddress.Any as your IP to initialise the listener.
As written in MSDN about TcpListener
IPAddress- An IPAddress that represents the
local IP address.
So it need to be a local IP address.

Get local IP address for socket

I'm looking to get the local IP address of the socket I just created. I need to be able to support a server with more than one NIC and communicate back to the requesting client what the direct IP address is to connect later on. I'm using for following code:
Socket rsock = null;
rsock= new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
rsock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0);
rsock.Bind(new IPEndPoint(IPAddress.IPv6Any, port));
rsock.Listen((int)SocketOptionName.MaxConnections);
After this point, .LocalEndPoint kicks out: [::]:PORT.
Background:
The reason I need the IP address is that a secondary connection by another client will need to return to this specific server. These servers will likely be behind a load balancer for the initial server selection so the client cannot resolve the IP address based on the host name.
Since you're binding to IPAddress.IPv6Any, the endpoint information will not be available before the first I/O operation occurs. The documentation says:
If you allow the system to assign your socket's local IP address and
port number, the LocalEndPoint property will be set after the first
I/O operation. For connection-oriented protocols, the first I/O
operation would be a call to the Connect or Accept method.
So, in your case, you will have to call Accept() before accessing LocalEndPoint in order to obtain meaningful information.

Categories