Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcl http POST-当通过rPi上的wlan0发送时,有效负载与标头分离_Http_Raspberry Pi_Tcl_Wifi_Raspbian - Fatal编程技术网

Tcl http POST-当通过rPi上的wlan0发送时,有效负载与标头分离

Tcl http POST-当通过rPi上的wlan0发送时,有效负载与标头分离,http,raspberry-pi,tcl,wifi,raspbian,Http,Raspberry Pi,Tcl,Wifi,Raspbian,我正在使用::http::geturl-query从rPi向ESP8266(第三方商业设备)发出一个http POST请求,其中包含一个小的json负载。它在通过eth0发送时工作,但在通过wlan0发送时失败。tcpdump显示,通过eth0发送时,消息作为单个数据包发送,但当通过wlan0发送时,有效负载从报头中分离,并在第二个数据包中发送。ESP8266很可能是由于其数据包接收器和/或http服务器的实现过于简单,因此似乎无法处理此拆分。它在接收到包含报头的数据包后发出200ok响应,并且

我正在使用
::http::geturl-query
从rPi向ESP8266(第三方商业设备)发出一个http POST请求,其中包含一个小的json负载。它在通过eth0发送时工作,但在通过wlan0发送时失败。tcpdump显示,通过eth0发送时,消息作为单个数据包发送,但当通过wlan0发送时,有效负载从报头中分离,并在第二个数据包中发送。ESP8266很可能是由于其数据包接收器和/或http服务器的实现过于简单,因此似乎无法处理此拆分。它在接收到包含报头的数据包后发出
200ok
响应,并且不处理请求的有效负载部分

实验上,我编写了由::http::geturl发送的相同请求消息文本,并使用
nc
通过wlan0发送;它作为单个数据包发送,并由ESP8266成功处理

有人知道为什么使用::http over wlan0发送请求会导致此拆分消息,如果可以采取任何措施来阻止它,该怎么办

代码片段:

set s [::http::geturl http://$ip/con?com=cli -query $data -type application/json]
set r [::http::ncode $s]
::http::cleanup $s
Raspbian软件包版本:

tcl8.6 8.6.9+dfsg-2
tcllib 1.19-dfsg-2

tcl_platform(engine)        = Tcl
tcl_platform(machine)       = armv7l
tcl_platform(os)            = Linux
tcl_platform(osVersion)     = 5.4.79-v7+

Tcl的http包将头刷新到套接字(即,在写入头和查询体之间执行实际的
write()
/
send()
)。对于HTTP服务器的任何正确实现来说,这都是很好的……但您不能使用它。出于某种原因,操作系统内核中的wlan和eth驱动程序对于如何处理这种情况有不同的策略,eth驱动程序决定在发送之前等待一段时间;Tcl完全没有配置套接字的这一方面,而是保持系统默认值。(我不知道如何配置操作系统默认设置。)

您可以随时复制http代码并注释掉
flush
。就是这个:

  • 第1463行:
    flush$sock


页面顶部有一个
下载
按钮/链接,用于该文件的确切版本(它与您的Tcl版本中的更改非常小,如果您在执行任何
包要求
调用之前明确地下载该文件,则应该是兼容的).Tcl的http包将头刷新到套接字(即,在写入头和查询体之间执行实际的
write()
/
send()
)。对于HTTP服务器的任何正确实现来说,这都是很好的……但您不能使用它。出于某种原因,操作系统内核中的wlan和eth驱动程序对于如何处理这种情况有不同的策略,eth驱动程序决定在发送之前等待一段时间;Tcl完全没有配置套接字的这一方面,而是保持系统默认值。(我不知道如何配置操作系统默认设置。)

您可以随时复制http代码并注释掉
flush
。就是这个:

  • 第1463行:
    flush$sock


页面顶部有一个
下载
按钮/链接,用于该文件的确切版本(它与您的Tcl版本中的版本相比只有很小的变化,如果您在执行任何
包要求
调用之前显式地下载该文件,它应该是兼容的)。

Eeek!那个设备正在假设HTTP使用的数据包数量?!那太可怕了,有时候很可能会出错。我怀疑开发人员一直在一个非常封闭的环境中运行,这对他们或使用他们通常提供的支持软件都不是问题。此特定功能仅需在初始设置(通常为一次性关闭)期间使用。祝你好运,我想。哎呀!那个设备正在假设HTTP使用的数据包数量?!那太可怕了,有时候很可能会出错。我怀疑开发人员一直在一个非常封闭的环境中运行,这对他们或使用他们通常提供的支持软件都不是问题。此特定功能仅需在初始设置(通常为一次性关闭)期间使用。我想祈祷吧。如果你碰巧构建了一条比MTU更长的消息,那么解决方法就会崩溃。基本的问题是TCP真的可以把事情分开,并且完全允许它选择这样做。依赖它而不这样做是非常不安全的。多纳尔,非常感谢你的快速回答和解决方案。我可以确认这已经为我解决了。如果你碰巧构建了一条比MTU更长的消息,那么解决方法就会崩溃。基本的问题是TCP真的可以把事情分开,并且完全允许它选择这样做。依赖它而不这样做是非常不安全的。多纳尔,非常感谢你的快速回答和解决方案。我可以确认这已经为我解决了。
$ ifconfig wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet 192.168.0.101  netmask 255.255.255.0  broadcast 192.168.0.255
inet6 fe80::ed38:71ab:13af:ae30  prefixlen 64  scopeid 0x20<link>
ether b8:27:eb:26:bf:94  txqueuelen 1000  (Ethernet)
Hardware    : BCM2835
Revision    : a020d3
Model       : Raspberry Pi 3 Model B Plus Rev 1.3
$ uname -a
Linux raspberrypi 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l GNU/Linux