java - Android HttpPost 消息不会通过线路发送其有效负载

标签 java android networking http-post

我正在尝试发送一个简单的字符串作为 HttpPost 消息的内容。

问题是,HttpPost 消息的正文永远不会到达线路。 (说 Wireshark 捕获)。 header 看起来还不错(包括正确计算的 Content-Length。

代码如下:

String url = "http://1.2.3.4/resource";
HttpClient client = new DefaultHttpClient();
String cmd = "AT+AVLPOS\r\n";
StringEntity se = new StringEntity(cmd);
se.setContentType("text/plain");  

HttpPost request = new HttpPost(url);
request.setHeader("Content-Type","text/plain");
request.setEntity(se);

HttpResponse response = client.execute(request);
[...]

字符串应该是 ASCII 编码的,但这是一个细节。

这是 WireShark 中显示的内容: -> 请注意,标有 + 的行是发送的内容,- 是接收的内容。

+POST /resource HTTP/1.1
+Content-Type: text/plain
+Content-Length: 11
+Host: 1.2.3.4
+Connection: Keep-Alive
+User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
+Expect: 100-Continue

-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked

-4
-OK

这是应该显示的内容(用 C# 编写了一个非常简单的控制台应用程序来执行此操作,它确实有效):

+POST /resource HTTP/1.1
+Content-Type: text/plain
+Host: 1.2.3.4
+Content-Length: 11
+Expect: 100-continue
+Connection: Keep-Alive
+
-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked
-
+AT+AVLPOS
+
-4
-OK
-
-48
-$AVTMR,99999999,204810,A,1234.2218,N,0123.1051,E,0,20,150811,0,REQ*69
-
-0
-

有什么建议吗?

最佳答案

我已经弄明白了,而且我今天学到了一些东西。

长话短说:通过 setting one of its parameters 禁用 HttpClient 的 HTTP Post expect-continue 握手,这将在一个 block 中发送整个请求消息。

//set up HttpPost request as before
HttpClient client = new DefaultHttpClient();
client.getParams().setBooleanParameter("http.protocol.expect-continue", false);
HttpResponse response = client.execute(request);
[...]

现在这就是我到达那里的方式,也许有一天这会对某人有所帮助。

首先我从 HttpEntityWrapper 派生并将其用作我的请求实体以查看什么时候被调用,并发现 EntitywriteTo(OutputStream) 方法根本没有被调用。

然后我开始研究为什么在“正确”行为的情况下,POST 请求没有一次全部发送,而是先发送请求 header ,然后接收响应 header ,然后发送请求正文。

这一切都与 HTTP Post expect-continue 握手有关。在 Haacked 上阅读更多相关信息. 如果在请求中发送了 expect-continue header ,Http 服务器应该回复一个 100 Continue 消息,表示“好的,我会接受你的消息”,或者一个错误,停止可能很长的 POST消息在它的轨道上。

不幸的是,我运行的 Web 服务器是在芯片上运行的基本实现,它发送了错误的回复(200 OK 而不是 100 Continue) .
.NET Http Client 的默认实现在这里似乎更加宽容:它将 200 消息视为 100 Continue耸耸肩,然后获取正在发送请求正文。

Android 的 Http 客户端实现(API 级别 7)并非如此。

接下来我尝试的是完全禁用 expect-continue 握手,以便让 HttpClient 发送整个请求。令我惊讶和高兴的是,网络服务器处理得很好,它回复了我想要的信息。耶!

关于java - Android HttpPost 消息不会通过线路发送其有效负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7078458/

相关文章:

java - 如何读取模板文件的内容进行更改并另存为新文件?

Java Hangman - 错误检查

java - tcp端口在java中接收数据很慢,但在php中接收数据很快

java - 为什么我已经四舍五入了,却得到了一个不终止的十进制扩展?

java - 推土机映射 JodaTime 属性未按预期工作

java - 生成 java POCO 并通过读取 json 文件来填充它们,所有这些都是动态的

android - 如何删除 ExpandableListView 中特定组(行)的箭头

java - Fragment 中的 RecyclerView 初始化

networking - 目标池 vs 后端服务 vs 区域后端服务差异?

c# - C# 中鼠标跟随绘图