问题
In a JSP app, in Tomcat, the following code used to produce the whole address of the page (from this answer):
String myUrl = "no network";
try {
Socket s = new Socket("www", 80);
myUrl = "http://"+s.getLocalAddress().getHostAddress()+":"+request.getLocalPort()+request.getRequestURI();
s.close();
} catch (Exception ex) {
} finally {
}
After that miUrl
would have the folowing value (not the real IP addr): http://111.101.101.2:8080/mypage.jsp
It has been working for several years.
A week ago miUrl
began having "no network" as value, indicating that an exception happened.
I issued ex.printStackTrace()
and is says: java.net.UnknownHostException: www
Creating a socked with the literal "www" used to work, now out of a sudden it stopped working.
Question:
- What's the technical reason why it worked for years?
- What's the technical reason why it stopped working all of a sudden?
- What would be the best way to programatically produce the whole address of any JSP page, that is not error-prone?
EDIT: It's a file-sharing app, running in the users's workstation, I want users to be able to copy the address to share links with others, and http://localhost:8080/downloadpage.jsp
(as shown in address field of browser) is no good for sharing. It would help if you show me how to get that same info without the socket hack.
回答1:
Like Beau Grantham said in the comment, there's a decent chance that this is a DNS issue. Try
$ ping www
and see if it resolves to anything. If you get
$ ping www
ping: cannot resolve www: Unknown host
$
then that's your issue.
I ran this locally and got:
~$ java TestResolve
java.net.UnknownHostException: www
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at TestResolve.main(TestResolve.java:7)
(I wouldn't expect this to be a hosts file since everybody is able to use the URL. Anyway 'www' is the sort of thing that you'd manage using DNS.)
As far as programmatically generating URLs, try
InetAddress.getLocalHost().getHostName()
if you're OK with a hostname. The other peers can probably resolve that. Otherwise
InetAddress localhost = InetAddress.getLocalHost();
InetAddress[] ips = InetAddress.getAllByName(localhost.getHostName());
Here you'll get a list of IPs for the host in question, corresponding to different interfaces. You might have to choose one based on the subnet, which presumably you could configure into the app.
回答2:
Solved the IP addr part without using a socket.
public String getIP(){
String ip="no network";
try {
Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
outmost:
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr instanceof Inet4Address){ // return the first IPv4 addr (127.0.1.1 is always last)
if (addr.isSiteLocalAddress()){
ip=addr.getHostAddress();
break outmost;
}
}
}
}
} catch (UnknownHostException e1) {
} catch (SocketException e) {
}
return ip;
}
Then
String miUrl = "http://"+getIP()+":"+request.getLocalPort()+request.getRequestURI();
来源:https://stackoverflow.com/questions/28487579/jsp-new-socket-www-80-stopped-working-after-years-of-working-ok