我正试图用php脚本将原始数据发送到嵌入式设备(基于Arduino Leonardo上的WizFi无线局域网模块的Wifi Shield)。我可以通过执行以下操作成功地将数据发送到设备:
unix终端(Mac OS X)上的echo -n "teststring" | nc xx.xx.xx.xx 4000
(X表示设备ip的占位符)
或使用Putty(在Windows XP下)和ip,端口,并选择"RAW"作为连接类型。
为了实现同样的目的,我尝试在php脚本中建立一个套接字(因为我想通过web表单将数据发送到设备)。
请参阅下面的示例代码:
$mysocket = socket_create(AF_INET, SOCK_RAW,255);
if ($mysocket === false) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("could not establish socket: [$errorcode] $errormsg");
}
// connect to socket
if (socket_connect($mysocket, 'xx.xx.xx.xx', 4000)) {
$text = "Socket connection seems successful!";
} else {
$text = "Unable to connect<pre>".socket_strerror(socket_last_error())."</pre>";
}
echo $text;
echo "Mystring: ";
echo $mystring;
echo "try to send data";
// send string to server
socket_write($mysocket, $mystring, strlen($mystring)) or die("Could not send data");
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
echo "errorcode:";
echo $errorcode;
echo $errormsg;
socket_close($mysocket);
套接字创建命令(参数的最后一个整数)的相应协议为:(我从服务器(Synology NAS)的/etc/protocols复制的列表。
<!-- language: none -->
ip 0 IP
icmp 1 ICMP
igmp 2 IGMP
ggp 3 GGP
tcp 6 TCP
pup 12 PUP
udp 17 UDP
idp 22 IDP
raw 255 RAW
在这个例子中,我使用了RAW。
我使用从shell运行这些示例php phpscriptinshell.php
因为我在使用SOCK_RAW选项时遇到了麻烦,因为我不被允许在基于web的php脚本上运行该命令。
所以最后我得到了错误输出:
套接字连接似乎成功!尝试发送数据php警告:socket_write():无法写入socket[22]:第37行/volume2/web/phpscriptinshell.php中的参数无效
警告:socket_write():无法写入socket[22]:第37行/volume2/web/phpscriptinshell.php中的参数无效ficus>php phpscriptinshell.php
当我使用协议的其他选项时。例如1对于ICMP,我没有得到错误,但是也没有传输数据。当我将0用于IP时,我得到"无法建立套接字:[93]不支持协议"当我使用6作为TCP时,终端变得不可靠,wifi芯片失去了与网络的连接。
所以我的问题是:
1) 当我尝试向套接字写入时,为什么会得到"无效参数"?
2) 使用TCP作为协议参数时会发生什么?
3) 使用php发送数据的正确方式应该是什么?
4) 你对解决这个问题有什么建议?
非常感谢你的提示!
作为Barmers提示之后的第二次尝试,我尝试了相同的脚本,但替换了
$mysocket = socket_create(AF_INET, SOCK_RAW,255);
通过
$mysocket = socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
再次使用
$mysocket = socket_create(AF_INET, SOCK_STREAM,6);
下面是我用作第二个脚本的第二个提示:
$socket = stream_socket_server("tcp://62.32.29.210:4000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />'n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "'n");
fclose($conn);
}
fclose($socket);
}
对不起,我对格式不太熟悉,所以请道歉。感谢上次让我的帖子看起来很好看的那个!
您想要:
$mysocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
SOCK_RAW
适用于需要访问数据包标头或某些低级别协议(如ICMP)的情况。