java.net.InetSocketAddress and java.net.SocketAddress Support IPv6? - java

Do java.net.InetSocketAddress and java.net.SocketAddress support IPv6?
Because the two classes that i have research and try it couldnt able me to view ipv6 connection it only able to view ipv4 connection anyone there have try and able to do the editing of the code?

A partial answer to your question, even though it may come too late to be of immediate use =).
I had the following lines of code attempt to connect to two different IP addresses:
// Defined port must be 13; that is NIST's default listening port.
SocketAddress socketAddress = new InetSocketAddress(currentIpAddress, 13);
socket = new Socket();
socket.connect(socketAddress, nistServerTimeoutInMilliseconds);
The first address works fine : '206.246.122.250'
The second address throws a 'java.net.SocketException: Protocol family unavailable' on the third line. That address is '2610:20:6F15:15::27'.
I thought at first that the problem was that IPv6 is not supported by InetSocketAddress in Java 1.7, but I found out that there are actually two classes that inherit from the InetAddress class in Java: Inet4Address and Inet6Address
http://docs.oracle.com/javase/6/docs/api/java/net/Inet4Address.html
http://docs.oracle.com/javase/7/docs/api/java/net/Inet6Address.html
This explains why my code, when trying to construct an Inet4Address using an IPv6 format was failing, and it may explain your issue as well.
Hope this helps =)
P.S. InetAddress and InetSocketAddress aren't the same class, but by testing for the kind of IP address you're dealing with, there may be a way to get around the problem.

Related

Socket Programming in Java using IPv6

I am new with the network programming and I have a few questions, that I couldn't find anywhere.
I don't understand if there is a difference in code between IPv4 and IPv6, when establishing connection.
Example Code :
Socket socket = new Socket(“127.0.0.1”, 5000)
The above code is used for IPv4, as I understood. But how do I initialize the socket if I want to use IPv6?
I don't understand if there is a difference in code between ipv4 and ipv6, when establishing connection.
There is little difference.
If you want to use an explicit IPv6 address, you will typically just instantiate the Socket with a IP address string in IPv6 syntax.
If you use a DNS name, then the available network stacks will determine whether you use IPv4 or IPv6:
If only one stack is supported (by the OS) and available, that is used.
If both stacks are available, the setting of the java.net.preferIPv4Stack property determines which is used.
For more information, read Networking IPv6 User Guide from the Oracle Java documentation.
For example this: Socket socket = new Socket("127.0.0.1", 5000) is used for ip4, as I understood. But how do I initialize the socket if I want to use ip6?
Socket socket = new Socket("::1", 5000);
See also: What is IPV6 for localhost and 0.0.0.0?

How to change source-ip(tcp) in Java

Is it possible to change TCP header in Java?
If it's possible, is there any [Change Header] method?
Answering the more narrow question from the title of your question ("How to change source ip in Java"), you can bind your socket to a local IP address and/or port before you connect it to a destination.
The IP address you bind to has to be an IP address that your machine has (otherwise, how could packets arrive back at your machine?). You can also take any unused, non-reserved port number to connect from.
Socket socket = new Socket();
socket.bind(new InetSocketAddress(9999));
// or: socket.bind(new InetSocketAddress(InetAddress.getByAddress(...), 9999));
socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 80));
More generally, the answer is no, you cannot just randomly change the TCP header. But there are plenty settings that you can do from Java that will affect what goes into the TCP header.
I'm wondering whether you'r thinking about to cheat the server by providing a random source ip. As far as I know, there's no way to do this in java.
And even if you have changed your ip address, i think you can not successfully "hand-shake" with the server, which means you can not establish a TCP connection with the server side.

unresolved socket address

This is more of a novice question, but I am unable to get the type of answer I am looking for on Google.
I was reading the InetSocketAddress class in java.net package and I came across this method named createUnresolved(String host, int port). This method creates an unresolved Socket.
Basically what do we mean by unresolved ? I have come across this term often in errors while compiling a program but never have understood it completely. Can anyone please explain the general meaning in java, and meaning with context to the said method.
Thanks.
I found this in a sun-blog:
But decided to keep it as is but use createUnresolved() to create an
InetSocketAddress, so that we know what was used to instantiate it. If
the user slapped in an IP address to begin with, we won't handle it.
(I think it was indistinguishable before) The token will have whatever
the user used (IP or name) in the beginning and in case of using name,
the key to the token cache won't change even with addr changes. So the
delegation token should continue to work.
Basically, it's a half-baked InetSocketAddress - so it's not the final iteration. It's an intermediary step..
And From API:
It can also be a pair (hostname + port number), in which case an
attempt will be made to resolve the hostname.
If resolution fails then the address is said to be unresolved but can
still be used on some circumstances like connecting through a proxy
So we didn't find the hostname, or the user-friendly "www.abc.com" method.
But if we are connecting via a proxy it's OK because that the proxy server handles the hostname .
I had the same exception: java.net.UnknownHostException: Host is unresolved: https://www.google.com
The problem was because I added the protocol https://, the problem is resolved after I removed https://
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("www.google.com", 443), 100);
socket.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}

MulticastSocket: Socket operation on non socket

I have some code like this:
InetAddress bind = InetAddress.getByName("192.168.0.1")
MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,0));
socket.setInterface(bind);
On windows 7 and windows XP with JDK6u17,I got a SocketException: Socket operation on non socket.
But if I change the line 2 to :
MulticastSocket socket = new MulticastSocket(0);
It's ok, and works find too with jdk6u14.
Why? thanks.
EDIT:
Why port 0 should be the matter?
MulticastSocket socket = new MulticastSocket(0);
Everything goes well with this code.But not
MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,port));
Whatever the port is.
As you are binding to a specific interface, calling setInterface() to the same interface is redundant. Remove it. It's only needed when you bind to INADDR_ANY, or in Java an InetAddress of null (or unspecified as a parameter).
To address errors in some of the other answers, and their implications:
Port zero is legal. It means a system-assigned port.
You only need a MulticastSocket for receiving multicasts. For sending, you can just use a DatagramSocket.
If the multicast interface needs to be specified, which it doesn't in this case, it can be done either via MulticastSocket.setInterface() or when calling joinGroup() or leaveGroup(). The latter option gives you granularity at the group level, but both techniques work. That's why they're both provided.
If you don't bind to a specific interface you should definitely call setInterface(). If you are on a multi-homed host you must to call joinGroup()/leaveGroup() once per interface, if you want to receive via all of them.
And a question: is 192.168.0.1 an IP address of an NIC on the local machine? It needs to be.
According to the documentation, you are supposed to instantiate it with a port number (thus 0 would be valid).
I am not so sure.
What's the constructor MulticastSocket(SocketAddress bindaddr) for.
And why it works fine with jdk6u14,but not jdk6u17?
And why it ok on windows 2003 server with jdk6u17?
On RHEL5.2 jdk1.4+
http://www.sockets.com/err_lst1.htm
Berkeley description: An operation was attempted on something that is not a socket. The specified socket parameter refers to a file, not a socket.
WinSock description: Same as Berkeley. The socket input parameter is not a valid socket handle (either it never was valid, it's a file handle (not a socket handle), or if it was a socket handle, it has been closed).
Detailed description:
select(): fails with WSAENOTSOCK if any socket in an fd_set is an invalid socket handle.
Developer suggestions: Did you close a socket inadvertently in one part of an application without keeping another part notified? Use socket state in an application and/or handle this error gracefully as a non-fatal error.
when the MulticastSocket created,socket.isClosed()==true
I haven't used these classes before, but the Exception occurs on line 3 when you call the setInterface method.
I would guess it's something to the effect that you're using the same reference twice or something.
I found a snippet of code that looked like this, maybe this is how you should be doing it:
MulticastSocket ms = new MulticastSocket(new InetSocketAddress(0));
ms.setInterface(InetAddress.getByName("192.168.0.1"));
You should first create the Multicast socket with a well known port - something higher than 1024 and less than 65535 - as already stated 0 means the operating system will choose a port for you (but then its going to be kinda random - which I guess you don't want).
For multicast - you generally need to set the interface to use on joinGroup() not on creation - e.g:
MulticastSocket socket = new MulticastSocket(2121);
InetSocketAddress socketAddress = new InetSocketAddress("localhost", 2121);
if (networkInterfaceName != null){
NetworkInterface ni = NetworkInterface.getByName(networkInterfaceName);
socket.joinGroup(this.socketAddress, ni);
}else {
socket.joinGroup(socketAddress.getAddress());
}
According to the MulticastSocket documentation you should use
Class D IP addresses in the range
224.0.0.0 to 239.255.255.255, inclusive
to bind a MulticastSocket. Apparently, the "192.168.0.1" is out of the multicast range.

IP Address not obtained in java

This code used to return my local ip address as 192.xxx.x.xxx but now it is returning 127.0.0.1 . Please help me why the same code is returning different value. Is there something that I need to watch at linux OS.
import java.util.*;
import java.lang.*;
import java.net.*;
public class GetOwnIP
{
public static void main(String args[]) {
try{
InetAddress ownIP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+ownIP.getHostAddress());
}catch (Exception e){
System.out.println("Exception caught ="+e.getMessage());
}
}
}
127.0.0.1 is the loopback adapter - it's a perfectly correct response to the (somewhat malfomed) question "what is my IP address?"
The problem is that there are multiple correct answers to that question.
EDIT: The docs for getLocalHost say:
If there is a security manager, its
checkConnect method is called with the
local host name and -1 as its
arguments to see if the operation is
allowed. If the operation is not
allowed, an InetAddress representing
the loopback address is returned.
Is it possible that the change in behaviour is due to a change in permissions?
EDIT: I believe that NetworkInterface.getNetworkInterfaces is what you need to enumerate all the possibilities. Here's an example which doesn't show virtual addresses, but works for "main" interfaces:
import java.net.*;
import java.util.*;
public class Test
{
public static void main(String[] args)
throws Exception // Just for simplicity
{
for (Enumeration<NetworkInterface> ifaces =
NetworkInterface.getNetworkInterfaces();
ifaces.hasMoreElements(); )
{
NetworkInterface iface = ifaces.nextElement();
System.out.println(iface.getName() + ":");
for (Enumeration<InetAddress> addresses =
iface.getInetAddresses();
addresses.hasMoreElements(); )
{
InetAddress address = addresses.nextElement();
System.out.println(" " + address);
}
}
}
}
(I'd forgotten just how awful the Enumeration<T> type is to work with directly!)
Here are the results on my laptop right now:
lo:
/127.0.0.1
eth0:
/169.254.148.66
eth1:
eth2:
ppp0:
/10.54.251.111
(I don't think that's giving away any hugely sensitive information :)
If you know which network interface you want to use, call NetworkInterface.getByName(...) and then look at the addresses for that interface (as shown in the code above).
When you use InetAddress.getLocalHost() you are not guaranteed to get a particular interface, ie. you could receive the loopback (127) interface or a connected one.
In order to ensure you always get an external interface, you should use the java.net.NetworkInterface class. The static getByName(String) class will give you the interface with the defined name (such as "eth0"). Then you can use the getInetAddresses() function to obtain the IP addresses (could be just one) bound to that interface.
NetworkInterface ni = NetworkInterface.getByName("eth1");
ni.getInetAddresses();
Check your /etc/host file. If you put 127.0.0.1 first, it will return this as result.
The correct way to get the ip address is to use NetworkInterface.getNetworkInterfaces() and run getInetAddresses() on each of them.
You can use the NetworkInterface.getNetworkInterfaces() method to retrieve an Enumeration of all of the network interfaces for your system.
For each of the NetworkInterface instances, you can then use the getInetAddresses() method to retrieve an Enumeration of all of the InetAddress instances associated with the network interface.
Finally, you can use the getHostAddress() method on each InetAddress instance to retrieve the IP address in textual form.
This is because you have a line in /etc/hosts like
127.0.0.1 localhost
you need to have
192.xxx.xxx.xxx localhost
Though please note that this would be very bad as to solve a code issue you should not modify linux config files. Not only is it not right (and risks breaking some other network aware apps on your linux box) it will also not work anywhere else (unless the admins of those boxes are also like minded).
javadoc for InetAddress.getLocalHost(); read "....an InetAddress representing the loopback address is returned." so it appears that the implementation of getLocalHost() is incorrect
on your UNIX and WIN boxes. The loopback address is nearly allways 127.0.0.1
Found this comment
"A host may have several IP addresses and other hosts may have to use different addresses to reach it. E.g. hosts on the intranet may have to use 192.168.0.100, but external machines may have to use 65.123.66.124. If you have a socket connection to another host you can call
Socket.getLocalAddress() to find out which local address is used for the socket."

Categories