【问题标题】:Android HttpPost message won't send its payload across the wireAndroid HttpPost 消息不会通过网络发送其有效负载
【发布时间】:2025-12-25 03:15:07
【问题描述】:

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

问题是,HttpPost 消息的正文永远不会到达网络。 (说 Wireshark 捕获)。标头看起来还不错(包括正确计算的 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
-

有什么建议吗?

【问题讨论】:

  • This 应该回答你的问题:)
  • @flob 我想我已经阅读了所有与 Android Http Post 相关的 SO 问题,包括那个问题 - 这就是我走到这一步的方式,但它仍然不起作用。

标签: java android networking http-post


【解决方案1】:

我已经想通了,而且我今天学到了一些东西。

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

//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 请求没有一次全部发送,而是发送了请求标头,然后接收到响应标头,然后请求正文已发送。

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

不幸的是,我运行的网络服务器是一个在芯片上运行的简单实现,它发送错误的回复(200 OK 而不是100 Continue)。
.NET Http Client 的默认实现在这里似乎更加宽容:它将200 消息视为100 Continue耸耸肩,然后开始发送请求正文。 p>

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

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

【讨论】:

  • 谢谢!!无论我尝试什么,我都有一个只是挂在 client.execute 上的 POST。您修复了这一天。
最近更新 更多