Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/268.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
Php 如何以编程方式生成连接重置?_Php_Python_Sockets_Web Applications_Tcp - Fatal编程技术网

Php 如何以编程方式生成连接重置?

Php 如何以编程方式生成连接重置?,php,python,sockets,web-applications,tcp,Php,Python,Sockets,Web Applications,Tcp,我相信您在尝试浏览网页时已看到“连接已重置”消息。(文本来自Firefox,其他浏览器有所不同。) 我需要根据需要生成消息/错误/条件,以测试变通方法 那么,如何以编程方式生成该条件呢?(如何从PHP或其他web应用程序语言中生成TCPRST) 注意事项和条件: 它不能是通用IP块。当不触发条件时,测试客户端必须仍然能够看到测试服务器 理想情况下,它将在web应用程序级别(Python、PHP、Coldfusion、Javascript等)完成。访问路由器是有问题的。访问Apache配置是一件痛

我相信您在尝试浏览网页时已看到“连接已重置”消息。(文本来自Firefox,其他浏览器有所不同。)

我需要根据需要生成消息/错误/条件,以测试变通方法

那么,如何以编程方式生成该条件呢?(如何从PHP或其他web应用程序语言中生成TCP
RST

注意事项和条件:

  • 它不能是通用IP块。当不触发条件时,测试客户端必须仍然能够看到测试服务器

  • 理想情况下,它将在web应用程序级别(Python、PHP、Coldfusion、Javascript等)完成。访问路由器是有问题的。访问Apache配置是一件痛苦的事

  • 理想情况下,它将通过获取特定网页来触发

  • 如果它在标准的商业web主机上工作,则会获得奖励

  • 更新: 发送
    RST
    不足以导致这种情况。见下面我的部分答案


    我有一个在本地机器上工作的解决方案,现在需要让它在远程主机上工作。

    我认为您需要相当突然地关闭低级套接字。您将无法从Javascript执行此操作。对于其他语言,通常需要获取底层套接字对象的句柄并手动关闭它


    我也怀疑你能通过Apache做到这一点,因为它是Apache,而不是你的应用程序。充其量,您的努力可能会产生一个HTTP 500错误,这不是您想要的。

    我建议您通过CLI通过自定义套接字执行此操作,因为干扰apache进程可能会很麻烦:

    #!/usr/bin/php -q
    <?php
    
    set_time_limit (0);
    
    $sock = socket_create(AF_INET, SOCK_STREAM, 0);
    
    socket_bind($sock, '1.1.1.1', 8081) or die('Could not bind to address');
    
    socket_listen($sock);
    
    $client = socket_accept($sock);
    sleep(1);
    $pid = getmypid();
    exec("kill -9 $pid");
    ?>
    
    #/usr/bin/php-q
    
    这将在Firefox中生成所需的错误,因为在读取之前连接已关闭

    如果你觉得自己胆子太大了,你可以把它放到一个网络脚本中,但我甚至不敢尝试,除非你拥有这个盒子,并且知道你在做什么。

    Update: 这个脚本工作得很好,足以测试我们的连接重置解决方案,所以这是一个部分答案

    如果有人提出了在远程主机上工作的完整解决方案,我很乐意将其作为答案


    在同一台机器上运行和测试时,以下脚本每次都有效。但在远程主机上运行时,浏览器会收到以下最后3个数据包:

    Source     Dest       Protocol  Info
    <server>   <client>   TCP       8081 > 1835 [RST] Seq=2 Len=0
    <server>   <client>   TCP       8081 > 1835 [RST] Seq=2 Len=0
    <server>   <client>   TCP       http > 1834 [ACK] Seq=34 Ack=1 Win=6756 Len=0
    

    这听起来像tcp连接是通过RST发送的。我想知道您是否可以让PHP to exec()命令实现这一点。也许让它查找属于其pid的任何连接(
    getmypid()
    ),然后杀死它们。建议@Fanis:是的,发送一个
    RST
    就可以了。谢谢你的建议;正在调查…Oops,仅发送
    RST
    是不够的。请参阅更新的Q和部分答案。这不适用于托管部署,因为使用了
    getmypid()
    exec()
    (加上试图终止进程!!!)。另外,
    kill
    是windows计算机上的有效命令吗?但是,这个脚本确实可以在我的本地开发机器上运行,需要注意以下几点:(1)时间限制最好设置为某个较高的值,300就足够了。(2) 最后3行是不需要的。似乎在Firefox尝试浏览端口之后,连接会自动重置——不需要PID kill。在我们的开发主机上还没有这样做。管理员明智地拒绝在远程主机上允许这样做。这种方法的性能也比设置
    SO\u LINGER
    的无风险方案差。
    <?php
        $time_lim       = 30;
        $listen_port    = 8081;
        echo
           '<h1>Testing generation of a connection reset condition.</h1>
            <p><a target="_blank" href="http://' .$_SERVER["HTTP_HOST"]. ':' .$listen_port. '/">
            Click here to load page that gets reset. You have ' . $time_lim . ' seconds.</a>
            </p>
           '
        ;
        flush ();
    ?>
    <?php
        //-- Warning!  If the script blocks, below, this is not counted against the time limit.
        set_time_limit ($time_lim);
    
        $socket     = @socket_create_listen ($listen_port);
        if (!$socket) {
            print "Failed to create socket!\n";
            exit;
        }
    
        socket_set_nonblock ($socket);  //-- Needed, or else script executes until a client interacts with the socket.
    
        while (true) {
            //-- Use @ to suppress warnings.  Exception handling didn't work.
            $client = @socket_accept ($socket);
            if ($client)
                break;
        }
    
        /*--- If l_onoff is non-zero and l_linger is zero, all the unsent data will be
            discarded and RST (reset) is sent to the peer in the case of a connection-
            oriented socket.
        */
        $linger     = array ('l_linger' => 0, 'l_onoff' => 1);
        socket_set_option ($socket, SOL_SOCKET, SO_LINGER, $linger);
    
        //--- If we just close, the Browser gets the RST flag but fails silently (completely blank).
        socket_close ($socket);
    
        echo "<p>Done.</p>";
    ?>