PHP 套接字包数据

PHP socket pack data

<?php

$desthost = "imap.gmail.com";
$port     = 993;
$conflag  = STREAM_CLIENT_CONNECT;

try
{
    $socket = stream_socket_client( "tcp://host:port", $errno, $errstr, 15, $conflag );

    fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) );
    $server_status = fread( $socket, 2048 );
    if ( $server_status == pack( "C2", 0x05, 0x00 ) )
    {
        // Connection succeeded
    }
    else
    {
        die( "SOCKS Server does not support this version and/or authentication method of SOCKS.\r\n" );
    }

    fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) );
    $server_buffer = fread( $socket, 10 );

    var_dump(unpack("C5", $server_buffer));


    if ( ord( $server_buffer[0] ) == 5 && ord( $server_buffer[1] ) == 0 && ord( $server_buffer[2] ) == 0 )
    {
        // Connection succeeded
    }
    else
    {
        die( "The SOCKS server failed to connect to the specificed host and port. ( " . $desthost . ":" . $port . " )\r\n" );
    }

    stream_socket_enable_crypto( $socket, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT );
}
catch ( Exception $e )
{
    die( $e->getMessage() );
}

if ( $socket === FALSE )
{
    die( "bad socket" );
}

//fwrite( $socket, "GET /\n" );
echo fread( $socket, 8192 );

此代码连接到代理并通过代理连接到imap。我不明白这个包是如何工作的?

什么意思 fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) ); ?

下一个代码是什么意思?

fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) );

我认为是 "CONNECT host:port"?有人可以解释一下吗?当我尝试发送命令“0000001 LOGIN login pass”时,imap returns 我出错了错误的语法。看来我应该打包这个命令或类似的东西。

https://en.wikipedia.org/wiki/SOCKS 中有 SOCKS 协议的概述。

这是一些用于快速连接到 SOCKS 代理的肮脏代码。

fwrite( $socket, pack( "C3", 0x05, 0x01, 0x00 ) ); 表示发送字节 5、1 和 0。

在初始连接请求中,这意味着“SOCKS 版本 5”,支持 1 身份验证方法,其中一种身份验证方法是 No authentication

if ( $server_status == pack( "C2", 0x05, 0x00 ) ) 正在检查服务器是否响应“Socks 版本 5,使用 No Authentication”。

fwrite( $socket, pack( "C5", 0x05, 0x01, 0x00, 0x03, strlen( $desthost ) ) . $desthost . pack( "n", $port ) ); 正在发送连接请求:

  • 5(SOCKS 版本 5)
  • 1(TCP 连接请求)
  • 0(预留)
  • 3(使用域名)
  • 域名
  • length
  • 域名
  • 网络字节顺序的端口号

if ( ord( $server_buffer[0] ) == 5 && ord( $server_buffer[1] ) == 0 && ord( $server_buffer[2] ) == 0 ) 正在检查服务器响应。

  • 5 袜子版本 5
  • 0 请求已获准
  • 0 保留字节。

还有更多的字段,但它忽略了它们,并希望它们恰好适合 10 个字节,如果 returns 返回域地址或 IPv6 地址,这可能不是真的。

至此,与远程服务器的连接建立。然后它将其升级到 TLS,否则应该按预期工作。

对于此时之后的 IMAP 命令,请确保它们以“\r\n”结尾。你实际上并没有为此显示你的代码,所以我们无法帮助调试它。

SOCKS5在RFC1928中正式指定。