PHP 从 Windows 机器上的套接字读取

Posted

技术标签:

【中文标题】PHP 从 Windows 机器上的套接字读取【英文标题】:PHP Read from socket on windows machine 【发布时间】:2012-06-03 17:17:27 【问题描述】:

我正在尝试编写一个“简单”的 php 程序,该程序应该向/从套接字(端口 23 上的 telnet)写入和读取字符串。

Socket 连接是使用 pfsockopen(或 socket_connect)函数进行的,它似乎可以正常工作(通过 wireshark 验证)。 问题是当我尝试使用 fread 或 socket_read 从套接字读取时。 这两个函数返回的缓冲区是不可读的(没有文本,只有特殊的 ascii 字符)。

假设 php 脚本正在 Windows XP PC 上运行。 您知道在 windows PC 和 telnet 协议上使用这些库有什么限制吗?

    $header1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0);

$fp=pfsockopen("10.129.127.33",23);
fputs($fp,$header1);
sleep(1);
$output=fread($fp,8164); 
echo $output;

【问题讨论】:

你能发布一些代码吗.. 特别是你如何连接以及你如何阅读连接 $fp=pfsockopen("10.129.127.33",23); fputs($fp,$TELNETHEADER);睡眠(1); $输出=fread($fp,1024); $stat=socket_get_status($fp); $output.=fread($fp, $stat["unread_bytes"]); 您是否连接到实际的telnet 服务器? 当然可以。问题是fread。这些是打印出来的字符 ²% ²▼ ■ ²↑ ²' ¹☺ ²♥ ¹♥ 您是否研究过 telnet 协议 (en.wikipedia.org/wiki/Telnet)?我认为它应该得到设置高位的字节。 【参考方案1】:
    连接成功了吗? 服务器是否允许在端口 23 上连接? 这可能会对您有所帮助

fputs($fp,"string");

do 
 
$output.=fread($fp, 80); 
// read line by line, or at least small chunks
$stat=socket_get_status($fp);

while($stat["unread_bytes"]);

$output = str_replace("\n", "<br>", $output);\\for new line in html
echo $output;

    以下是我使用的 TELNET 标头

    $header1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).chr(0x27).chr(0xFF).chr(0xFD).ch.(0x01).chr(0xFF).chr(0xFB).chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0);
            $header2=chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);
    
    $fp=fsockopen("192.168.125.6",23);  
    
    
    //**********Send telnet header****************
    
    fputs($fp,$header1);
    
    usleep(1000);
    
    fputs($fp,$header2);
    
    usleep(1000);
    

【讨论】:

【参考方案2】:
<?php
# Generating output by telneting a router

$username='myusername';
$password='mypassword';
$ip="192.168.0.1";

    $Telnet_Header = chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0);
$Telnet_Header2 = chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);
$Port = 23;
$Conn = fsockopen($ip, $Port);
fputs($Conn,$Telnet_Header);
sleep(1);
fputs($Conn,$Telnet_Header2);
sleep(1);
fputs($Conn,$username."\r");
sleep(5);
fputs($Conn,$password."\r");
sleep(1);
fputs($Conn,$username."\r");
sleep(5);
fputs($Conn,$password."\r");
sleep(5);
fputs($Conn,"en \r"); 
   sleep(3);
fputs($Conn,"conf t\r"); 
   sleep(3);
fputs($Conn,"terminal length 0\r"); 
   sleep(3);
fputs($Conn,"sh run\r"); 

   $output="";
do

    $output.=fread($Conn, 1000);
    $stat=socket_get_status($Conn);
while($stat["unread_bytes"]);
$output = explode("\n", $output);
for ($i=6;$i<count($output)-1;$i++)
    
    echo ($output[$i]."\n");
    

?>

【讨论】:

以上是关于PHP 从 Windows 机器上的套接字读取的主要内容,如果未能解决你的问题,请参考以下文章

PHP TCP 套接字连接限制 - Windows 服务器

代号一 - 无法从真实设备上的套接字读取

Postgres JDBC 客户端卡在从套接字读取

PHP 警告:socket_read():无法从套接字 [104] 读取:连接被对等方重置

C# Windows 应用程序从流套接字读取数据不可理解

mIRC 套接字从 url 读取文本