问题
In my IIS i have created Web Api and it's Project Url is http://localhost:54444.
I am albe to connect to this Url from my browser in Windows8, however I am not able to do so in my android emulator browser via http://10.0.2.2:54444
.
My android browser is able to connect to google.com.
I am also trying to make an client in Eclipse using http://loopj.com/android-async-http/ library:
Log.v("bopzy_debug", "Testing HTTP Connectivity");
System.out.println("123");
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://10.0.2.2:54444/api/values/",
// client.get("http://google.pl",
new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String response) {
Log.v("bopzy_debug", response);
}
@Override
public void onFailure(Throwable error, String content)
{
System.out.println("onFailure");
System.out.println(content);
Log.w("bopzy_debug", error);
}
@Override
public void onFinish() {
System.out.println("onfinish:");
Log.v("bopzy_debug", "Finished..");
}
});
}
The LogCat info I'm getting:
07-18 09:18:17.471: V/bopzy_debug(1354): Testing HTTP Connectivity
07-18 09:18:17.471: I/System.out(1354): 123
07-18 09:18:17.621: I/System.out(1354): onFailure
07-18 09:18:17.644: I/System.out(1354): <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
07-18 09:18:17.644: I/System.out(1354): <HTML><HEAD><TITLE>Bad Request</TITLE>
07-18 09:18:17.644: I/System.out(1354): <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
07-18 09:18:17.644: I/System.out(1354): <BODY><h2>Bad Request - Invalid Hostname</h2>
07-18 09:18:17.652: I/System.out(1354): <hr><p>HTTP Error 400. The request hostname is invalid.</p>
07-18 09:18:17.652: I/System.out(1354): </BODY></HTML>
07-18 09:18:17.652: W/bopzy_debug(1354): org.apache.http.client.HttpResponseException: Bad Request
07-18 09:18:17.652: W/bopzy_debug(1354): at com.loopj.android.http.AsyncHttpResponseHandler.sendResponseMessage(AsyncHttpResponseHandler.java:235)
07-18 09:18:17.652: W/bopzy_debug(1354): at com.loopj.android.http.AsyncHttpRequest.makeRequest(AsyncHttpRequest.java:79)
07-18 09:18:17.652: W/bopzy_debug(1354): at com.loopj.android.http.AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:95)
07-18 09:18:17.652: W/bopzy_debug(1354): at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:57)
07-18 09:18:17.652: W/bopzy_debug(1354): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
07-18 09:18:17.652: W/bopzy_debug(1354): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
07-18 09:18:17.652: W/bopzy_debug(1354): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
07-18 09:18:17.652: W/bopzy_debug(1354): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
07-18 09:18:17.652: W/bopzy_debug(1354): at java.lang.Thread.run(Thread.java:856)
07-18 09:18:17.682: I/System.out(1354): onfinish:
07-18 09:18:17.682: V/bopzy_debug(1354): Finished..
I have added:
<uses-permission android:name="android.permission.INTERNET" />
to AndroidManifest.xml file.
Any suggestion will be appreciated.
回答1:
The OP seemed to have found a solution, but for posterity's sake, here's a more thorough explanation of what's happening and how to fix it.
I had a similar issue using a local Rails server. I realized that I didn't understand the relationship between the IP address and the hostname. They're different and if we're not careful, we can run into issues.
The Relationship Between IP Address and Hostnames in the Host File
Hostnames can be assigned to the IP addresses, but IP addresses are not assigned to hostnames.
hostname --> IP Address
This relatioship seems trivial, but it's important to understand that it's a one way relationship. The hostname takes you to the IP address, but the IP address is not aware of the hostname.
Lets say we have two hostnames that point to 127.0.0.1: localhost and localdev. Now lets say I have a server listening on localhost:3000. If I type in localdev:3000, what would you expect to happen?
Tha answer is nothing.
Localhost and localdev may be pointing to the same IP address, but the IP address doesn't point back to the hostnames. With this relationship, data only goes one way.
localhost --> 127.0.0.1 <-- localdev
Listening on Localhost and Listening on 127.0.0.1 are not the same thing
I noticed that when I started a Ruby on Rails server, the logs specified that the server was listening on localhost:3000. In my browser, when I hit localhost:3000, I'd see the website I'm building.
Now localhost is, by default, pointing to 127.0.0.1, so what would happen if I went to 127.0.0.1:3000? Answer: nothing. The Ruby server does not say listening on 127.0.0.1, but localhost. Even though localhost eventually goes to 127.0.0.1, 127.0.0.1 is not the address that the server is listening on.
Now, if the server was listening on 127.0.0.1 and you hit localhost from your browser, you will still get your website because localhost forwards everything to 127.0.0.1. Consequentially, if you try to hit another hostname pointing to 127.0.0.1 (such as localdev was from the previous example), that will also work.
Clearing Up 10.0.2.2 and Localhost's Relationship
Once we understand the relationship between localhost and 127.0.0.1, we can better understand the relationship between 10.0.2.2 coming from Android and localhost on your machine. The Android docs on Using the Emulator says that 10.0.2.2 links to:
Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine)
Notice that it points to the IP address, not the hostname. If we had the server listen on 127.0.0.1 instead of localhost, the emulator will be able to successfully send messages to our server.
来源:https://stackoverflow.com/questions/17719496/bad-request-when-trying-to-connect-to-iss-7-express-from-android-emulator