Java Socket, binding to local port
Asked Answered
E

2

10

I am trying to bind the Socket on the client side to any particular local port, in this code I used 20000.

Normal connections such as below works just fine. But does not allow for me to choose the local port.

hostSocket = new Socket(host,80);

So I tried this:

hostSocket = new Socket(host, 80, InetAddress.getLocalHost(), 20000);

and this:

hostSocket = new Socket();
hostSocket.bind(new InetSocketAddress("localhost", 20000));
hostSocket.connect(new InetSocketAddress(host,80));

But they both leave me with this exception... in the second case the exception occurred on the connect call. I'm not really sure what I am missing and I would love some pointers.

java.net.SocketException: Invalid argument or cannot assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:546)
at java.net.Socket.connect(Socket.java:495)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.connect(NetflixPrefetchingAgent.java:98)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.run(NetflixPrefetchingAgent.java:164)
at java.lang.Thread.run(Thread.java:679)
Exception in thread "Thread-19" java.lang.NullPointerException
at com.mb.proxy.netflix.NetflixPrefetchingAgent.prefetchChunk(NetflixPrefetchingAgent.java:272)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.run(NetflixPrefetchingAgent.java:176)
at java.lang.Thread.run(Thread.java:679)
Emeric answered 5/2, 2013 at 2:34 Comment(3)
Why do you care what the outbound local port is?Destruction
@Brian Roach I'm throttling bandwidth on particular ports for research purposes. For it to work I need to know which ports certain parts of my application are using.Emeric
I believe you have to bind to the actual outbound IP address (not localhost which is going to resolve to 127.0.0.1) - I'd have to test it though.Destruction
D
36

You have to bind to the external (outbound) IP address of your machine, not localhost (127.0.0.1).

The following works on my box without issue:

Socket s = new Socket();
s.bind(new InetSocketAddress("172.16.1.102", 5000));
s.connect(new InetSocketAddress("google.com", 80));

Where 172.16.1.102 is the NAT'd private network address assigned to this box via DHCP from my router.

Destruction answered 5/2, 2013 at 2:51 Comment(2)
Thanks Brian, I just tested it and it works. Sorry I don't have the appropriate amount of reputation to upvote your answer.Emeric
HELLO @BrianRoach we should not bind and connect to the same InetSocketAddress ie the server ?? it is like we need to bind to one socketaddress and connect to another ? i was bit confused. could you please clarify thisUnhesitating
S
4

Brian's answer is spot on in identifying the issue.

However, you don't need the IP address of the outbound interface because you can simply specify 0.0.0.0 for "any address". The correct outbound interface will then be chosen automatically. This is much like when you connect without binding first.

Moreover, the easiest way to specify 0.0.0.0 as the address is to omit the parameter.

Therefore:

hostSocket = new Socket();
hostSocket.bind(new InetSocketAddress(20000));
hostSocket.connect(new InetSocketAddress(host, 80));
Sciatica answered 31/3, 2018 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.