Android HttpPost消息不会通过网络发送其有效负载

Cri*_*scu 5 java networking android http-post

我正在尝试发送一个简单的字符串作为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);
[...]
Run Code Online (Sandbox Code Playgroud)

字符串应该是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
Run Code Online (Sandbox Code Playgroud)

应该是显示出来的(在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
-
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Cri*_*scu 13

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

长话短说:禁用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);
[...]
Run Code Online (Sandbox Code Playgroud)

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

首先,我从派生HttpEntityWrapper和使用,作为我的请求实体,看看有什么被调用时,并发现了EntitywriteTo(OutputStream)方法,根本就不会叫.

然后我开始研究为什么,在"正确"行为的情况下,POST请求没有一次全部发送,而是发送了请求头,然后收到响应头,那么请求体是发送.

这都与HTTP Post expect-continue握手有关.在Haacked上了解更多相关信息.如果在请求中发送了expect-continue标头,那么Http服务器应该回复一条100 Continue消息,表示"OK,我将接受您的消息",或者出现错误,在其轨道中停止可能很长的POST消息.

不幸的是,我运行的Web服务器是一个在芯片上运行的简单实现,它发送错误的回复(200 OK而不是100 Continue).
.NET Http Client的默认实现似乎更宽容:它将200消息视为100 Continue,shrugs,并开始发送请求体.

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

我试过的下一件事是expect-continue完全禁用握手,以便让HttpClient发送整个请求.令我惊讶和高兴的是,Web服务器处理得很好,它回复了我想要的信息.好极了!