Why is there not a parameterless implementation of TcpClient.Connect? - c#

Consider the following:
IPEndPoint ep = new IPEndPoint(ip, 0);
TcpClient tcpClient = new TcpClient (ep);
tcpClient.Connect(ep);
Why must I tell the tcpClient to first bind to ep and the connect to ep. I seems strange compared to just Connect() to the already bound end point.

The constructor that accepts an IPEndpoint is meant for binding a local endpoint address. Connect is meant to be passed a remote endpoint address. One of these two things is in contradiction with the other.
constructor:
Initializes a new instance of the TcpClient class and binds it to the specified local endpoint.
Connect:
Connects the client to a remote TCP host using the specified remote network endpoint.
But since we don't know whether ep is a local or remote endpoint, I can't tell you which one is wrong. I would guess at a local endpoint since you've specified 0, in which case you need to identify a different endpoint for your Connect call - what are you trying to connect to?

Not sure if I'm missing something here, but there is a default constructor.
http://msdn.microsoft.com/en-us/library/aa329755(v=vs.71).aspx

Related

How to run client and server UDP listeners on the same machine

Both client and server send and receive on a given port. In production they are on separate machines and there is no problem. In development it would be a great deal more convenient to run them on the same machine and avoid the need for deployment and setting up and tearing down a remote debug session.
I tried this
var uc = new UdpClient();
var ep = new IPEndPoint(address, port);
uc.ExclusiveAddressUse = false;
uc.Client.Bind(ep);
and it doesn't barf but I still can't bind multiple listeners to the same endpoint. After the fact I discovered that ExclusiveAddressUse defaults to false anyhow so this approach produces nothing but extra code.
Is this possible and if so how?
You obviously cant use the same port on the same machine, just use an #if directive for debug and change your ports accordingly
The following might help
Client
#if DEBUG
uc client = new UdpClient(34534);
#else
uc client = new UdpClient();
#endif
UdpClient Constructor (Int32)
Initializes a new instance of the UdpClient class and binds it to the
local port number provided.
Remarks
This constructor creates an underlying Socket and binds it to the port
number from which you intend to communicate. Use this constructor if
you are only interested in setting the local port number. The
underlying service provider will assign the local IP address. If you
pass 0 to the constructor, the underlying service provider will assign
a port number. If this constructor is used, the UdpClient instance is
set with an address family of IPv4 that cannot be changed or
overwritten by a connect method call with an IPv6 target.
Disclaimer, totally untested, just read the documentation, possibly wrong :)

TCP Client problems

I have few questions (and problems) about the tcp client class.
1. What IP should I give to it constructor, mine or the remote host that I want to connect to? because in MSDN I see that the constructor takes a local ip endpoint and I can't understand it.
2. What may be the reason for such statement:
TcpClient client = new TcpClient(ip.Text, port: portNum);
to stop the code from running without throwing an exception?
1. The IP you should give to the constructor
You should give the IP you want to connect, look about the IPAddress class.
2. The reason of the statement
Why did you type port: portNum ?
Just write like what is writed in the official documentation :
//Creates a TCPClient using host name and port.
TcpClient tcpClientB = new TcpClient ("www.contoso.com", 11000);
System.Net.Sockets.TcpClient has four constructors. The two constructors that seem to be the source of confusion are:
TcpClient(IPEndPoint) - binds it to the specified local endpoint.
TcpClient(String, Int32) - connects to the specified port on the specified host.
Constructor #1 is useful if your computer has more than one NIC (e.g. Ethernet and WiFi) and you want to pick which one to use. If you construct your TcpClient instance this way, then you would explicitly call TcpClient.Connect to connect the remote host and port number.
Constructor #2 creates the TcpClient instance (picking a local endpoint automatically) and immediately connects using the supplied remote host and port.

TcpClient(IPEndPoint localEP), choosing correct localEp?

I'm driving myself crazy.
Microsoft provides an awesome way of binding a local network adaptor and port for a new TCPClient by using the constructor:
TcpClient newClient = new TcpClient(IPEndPoint localEP);
Given a general remoteEndPoint, either IPv4 or IPv6, and assuming MANY possible localEPs, there does not seem to be a sensible way of determining which localEP to bind to before then calling:
TcpClient.Connect(IPEndPoint remoteEP)
.net does provide a parameterless TcpClient constructor, which will automatically determine which localEP is best when calling .Connect but unfortunately that does not support IPv6 targets.
My first thought was to access the IP routing table and working out myself which adaptor to use but it seems .net does not provide that functionality either.
I have found a solution which involves a P.Invoke to GetBestInterface() but unfortunately I need to be able to deploy in Mono so really need a managed solution.
My question/problem is: Given a known remoteEP, and a list of all known localEPs how do I correctly choose the correct localEP when instantiating the tcpClient so that the connect method is successful.
If what you're asking is what to use for localEP, you could use new IPEndPoint(IPAddress.Any, myPort) This will bind to any available IP addresses on the local computer and use port myPort. That way something can connect to the computer with whatever IP it likes. If you have multiple IPs (e.g. NICs) it can connect, if i has IPv4 and IPv6, it can connect to either.
e.g. :
var client = new TcpClient(new IPEndPoint(IPAddress.Any, myPort));
But, you can normally just use new TcpClient();

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.

How to send request from different static IP address to a any website?

I am sending HTTP request using C#. (http://codesamplez.com/programming/http-request-c-sharp)
I have dedicated server on.I have purchased more static IPs.
How can I send request using these different IPs.
What you want to do is bind to a specific network adapter. By default the LocalEndpoint is null so your connection will be to assigned an adapter. You can specify what to bind to using HttpWebRequest.ServicePoint.BindIPEndPointDelegate.
var req = (HttpWebRequest)WebRequest.Create("http://google.com/");
req.ServicePoint.BindIPEndPointDelegate = BindTo;
using (req.GetResponse());
static IPEndPoint BindTo(ServicePoint servicepoint, IPEndPoint remoteendpoint, int retrycount)
{
IPAddress ip = IPAddress.Any; //This is where you specify the network adapter's address
int port = 0; //This in most cases should stay 0. This when 0 will bind to any port available.
return new IPEndPoint(ip, port);
}
Here is some more information on binding from msdn.
Use the Bind method if you need to use a specific local endpoint. You
must call Bind before you can call the Listen method. You do not need
to call Bind before using the Connect method unless you need to use a
specific local endpoint. You can use the Bind method on both
connectionless and connection-oriented protocols.
Before calling Bind, you must first create the local IPEndPoint from
which you intend to communicate data. If you do not care which local
address is assigned, you can create an IPEndPoint using IPAddress.Any
as the address parameter, and the underlying service provider will
assign the most appropriate network address. This might help simplify
your application if you have multiple network interfaces. If you do
not care which local port is used, you can create an IPEndPoint using
0 for the port number. In this case, the service provider will assign
an available port number between 1024 and 5000.
If you use the above approach, you can discover what local network
address and port number has been assigned by calling the
LocalEndPoint. If you are using a connection-oriented protocol,
LocalEndPoint will not return the locally assigned network address
until after you have made a call to the Connect or EndConnect method.
If you are using a connectionless protocol, you will not have access
to this information until you have completed a send or receive.

Categories