TcpClient - bind to/use a specific IP. (vb.net)

J

Jan Vinten

Hi all,

I got into some trouble trying to bind to a specific IP address.

Code:
Private mobjClient As TcpClient

mobjClient = New TcpClient(IPAddress.Parse("10.16.104.87").ToString,
8892)

mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead,
Nothing)

The above code works perfectly along with the rest of the code - but
what I am trying to figure out is how to use a specific IP to connect
from.

I have 4 IP addresses and I want to use a the "3" one. How can I tell
the code to use that one IP?

Currently I have tried with:
mobjClient.Client.Bind(New
IPEndPoint(IPAddress.Parse("10.24.36.22"), 8892))

But that doesnt work. Can anyone help me out here?

/ Jan
 
A

Armin Zingler

Jan Vinten said:
Hi all,

I got into some trouble trying to bind to a specific IP address.

Code:
Private mobjClient As TcpClient

mobjClient = New TcpClient(IPAddress.Parse("10.16.104.87").ToString,
8892)

mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead,
Nothing)

The above code works perfectly along with the rest of the code - but
what I am trying to figure out is how to use a specific IP to
connect from.

I have 4 IP addresses and I want to use a the "3" one. How can I
tell the code to use that one IP?

Currently I have tried with:
mobjClient.Client.Bind(New
IPEndPoint(IPAddress.Parse("10.24.36.22"), 8892))

But that doesnt work. Can anyone help me out here?


List network interfaces and IP addresses:

Imports System.Net
Imports System.Net.NetworkInformation

'...

Dim NInterfaces = NetworkInterface.GetAllNetworkInterfaces

For Each NInterface In NInterfaces
Dim Props = NInterface.GetIPProperties()
Dim Addresses = Props.UnicastAddresses

Debug.Print(NInterface.Description)

For Each Address In Addresses
Debug.Print(" " & Address.Address.ToString)
Next
Next


For the TCPClient:

mobjClient = New TcpClient(New IPEndPoint(Address.Address, 8892))

"Address.Address" is what you see in the inner loop before.


Armin
 
J

Jan Vinten

List network interfaces and IP addresses:

Imports System.Net
Imports System.Net.NetworkInformation

'...

Dim NInterfaces = NetworkInterface.GetAllNetworkInterfaces

For Each NInterface In NInterfaces
Dim Props = NInterface.GetIPProperties()
Dim Addresses = Props.UnicastAddresses

Debug.Print(NInterface.Description)

For Each Address In Addresses
Debug.Print(" " & Address.Address.ToString)
Next
Next

For the TCPClient:

mobjClient = New TcpClient(New IPEndPoint(Address.Address, 8892))

"Address.Address" is what you see in the inner loop before.

Armin

Hi Armin,

Thank you for your reply.

I guess the easiest way to find all IP addresses are like:
Dim ipE As IPHostEntry = Dns.GetHostEntry(Dns.GetHostName())
Dim IpA() As IPAddress = ipE.AddressList

Now IpA contains all IP addresses in a array. But that is another
story!

The main issue was that I wanted to connect to a TCP server using a
specific IP address. (firewall issues) I could only have the TcpClient
use the first available IP address on my Windows machine. I have 4
IP's and wanted the TcpClient to use the 3. one. That I could not get
to work.

So I spend hours searching the net when I came across Socket coding
instead. Now I am able to bind to a specific IP - see below:

Private ClientSocket As Socket

ClientSocket = New Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp)

Dim endpoint As New IPEndPoint(IPAddress.Parse("10.16.104.87"), 8892)

Dim bindaddress As New IPEndPoint(IPAddress.Parse("10.24.36.22"), 0)
ClientSocket.Bind(bindaddress)

ClientSocket.BeginConnect(endpoint, AddressOf Connected, Nothing)

And it is now working. ;o)

/ Jan
 
A

Armin Zingler

Could you give this same type example for UDP, please? I have an IP
address (local subnet) or URL (remote access) and a port number. I
need to send one integer and receive 38 integers back UDP.

I have it working but by using the old VB6 style control and Strict
On does not like it so I have to run with it off.

This seems to easy but I can't find anything that works for UDP
(plenty of TCP & HTTP). Any help or pointer(s) to sample code would
be appreciated.

I'm not sure. Have you tried System.Net.Sockets.UdpClient? My example dealed
only with IP which, as you probably know, is one layer below UDP and not an
alternative.

Have a look here: http://msdn.microsoft.com/en-us/library/c19ex43h.aspx and
UDP sub topic http://msdn.microsoft.com/en-us/library/tst0kwb1.aspx


Armin
 
A

Armin Zingler

It is really sad that the creators/documenters of VS think that
almost no one will use Visual Basic for anything interesting.

Unfortunatelly I agree. Or I'd better say, I agree because it's
unfortunatelly true. Sometimes I also get the impression that we are
supposed to write msgbox "hello world!" all day long.


Armin
 
S

Stephany Young

For starters, try this:

Dim _socket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp)

Dim endpoint As New
IPEndPoint(Dns.GetHostEntry("pccbackup.no-ip.info").AddressList(0), 14917)

Console.WriteLine(_socket.SendTo(BitConverter.GetBytes(1119), endpoint))

Dim _buffer(1023) As Byte

Dim _result = _socket.Receive(_buffer, 1023, SocketFlags.None)

Console.WriteLine(_result)

For _i = 0 To _result - 1
Console.WriteLine(_buffer(_i))
Next

Console.WriteLine("***")

The result of the Socket SendTo method is the number of bytes sent. This is
clearly stated in the documentation.

Are you sure that you are expecting 38 bytes to be received. The above gets
36.

Note that changing SocketFlags.None to SocketFlags.Broadcast for the Receive
will result in a 10045 exception.

The big 'trick' is to isolate the steps down to a set that works and then
work up from there.

Also you MUST be aware that UDP is a 'connectionless' protocal and therefore
the socket cannot give you any feedback as to whether or not anything you
send is actually received at the other end.



I feel like I am getting close but nothing useful is happening and I
have an error message and code when I look at the variables. Here's the
send routine:

------------------------------------------------------

(way up top, among others)
Imports System.Net.Sockets

(in the project module)
Friend Const InverterPort As Integer = 14917

(in the form)
dim rc as integer

Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp)

Dim broadcast As IPAddress = IPAddress.Parse("10.0.0.101") '
replace with pccbackup.no-ip.info for remote testing/operation 24x7.

Dim endpoint As New IPEndPoint(broadcast, InverterPort)

Dim iUniqueBox As Integer = 1119

Dim sendbuf As Byte() = BitConverter.GetBytes(iUniqueBox)

rc = s.SendTo(sendbuf, endpoint)

------------------------------------------------------

When it runs, rc gets set to 4. I see no documentation of what this
means. Maybe that is the number of bytes sent??? They loosely refer to
knowing how many bytes are sent but never reference or code this int
value in the examples I have found.

When I breakpoint on s.SendTo and hover on the "endpoint" variable, it
gives a box with "Address" as the name of the first item in the list.
When I hover on "broadcast" in that info box, it gives a box with an
error code 10045 and a message saying that "The attempted operation is
not supported for the type of object referenced." I don't get this
displayed to me, but see it there.

It seems to want to send the correct four bytes out but nothing happens.
I never get an answer. I don't think anything is going out. I have
only replaced the previous ActiveX send statement with this routine. The
receive routine is untouched and working so far. Just doing a little at
a time.

By changing "10.0.0.101" to "pccbackup.no-ip.info" anyone can try this
remotely at any time of the day or night and see what I mean. It should
return 38 integers.

As usual, many thanks for any pointers. This little deal is making me
crazy and has been for six months! I think this is as simple as I can
make it and still not getting the job done.

Still lost Mike

P.S. Here's the Java send/receive routine this is based on:

//Step 3) Send the 4 byte request packet to port 14917
InetAddress address = InetAddress.getByName(args[0]);
DatagramPacket packet = new DatagramPacket(buffer, 4, address, 14917);
socket.send(packet);
System.out.println( "" );
System.out.println( "Sending Packet to: "+ args[0] );
//Step 4) Get the response packet from the PVM1010
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
System.out.println( "" );
System.out.println( "Response Packet size: "+ packet.getLength() );
System.out.println( "" );

-----------------------------------------------------------

I'm not sure. Have you tried System.Net.Sockets.UdpClient? My example
dealed
only with IP which, as you probably know, is one layer below UDP and not
an
alternative.

Have a look here: http://msdn.microsoft.com/en-us/library/c19ex43h.aspx
and
UDP sub topic http://msdn.microsoft.com/en-us/library/tst0kwb1.aspx


Armin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top