You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中通过代理服务器实现TCP Socket连接Minecraft服务器

Using a Proxy for Minecraft TCP Connections in PHP

Got it, let's adjust your existing Minecraft connection code to work with a proxy. Since Minecraft uses raw TCP for its protocol, you have two common options: SOCKS5 proxy (the most straightforward for generic TCP traffic) or an HTTP proxy that supports CONNECT tunneling. Let's break down both approaches.


Option 1: Using a SOCKS5 Proxy

SOCKS5 is built to handle arbitrary TCP traffic, making it the ideal choice for Minecraft. Here's how to modify your code to use a SOCKS5 proxy:

Step-by-Step Modifications

  1. Connect to your SOCKS5 proxy instead of the Minecraft server directly.
  2. Complete the SOCKS5 handshake to inform the proxy of your target Minecraft server's address and port.
  3. Once the handshake succeeds, send your Minecraft packets just like you did originally.

Modified Code

// Proxy configuration
$proxyHost = 'your-proxy-ip';
$proxyPort = 1080; // Default SOCKS5 port
$proxyAuth = null; // Leave null if no auth, or use ['username' => 'user', 'password' => 'pass']

// Minecraft server details (keep your original values here)
$ip = 'mc.example.com';
$port = 25565;
$proto = 760; // Adjust to your Minecraft protocol version

function makeVarInt($value) {
    // Your existing makeVarInt implementation here
    $result = '';
    do {
        $byte = $value & 0x7F;
        $value >>= 7;
        if ($value != 0) {
            $byte |= 0x80;
        }
        $result .= chr($byte);
    } while ($value != 0);
    return $result;
}

function generateRandomString($length) {
    // Your existing generateRandomString implementation here
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

// 1. Connect to the SOCKS5 proxy
$socket = @stream_socket_client("tcp://$proxyHost:$proxyPort", $errno, $errstr, 10);
if ($errno > 0) {
    echo "Proxy connection ERROR: " . $errstr . PHP_EOL;
    exit;
}

// 2. Perform SOCKS5 handshake
// Send version and authentication methods
$authMethods = "\x00"; // No authentication
if ($proxyAuth) {
    $authMethods = "\x02"; // Username/password auth
}
fwrite($socket, "\x05" . chr(strlen($authMethods)) . $authMethods);

// Read proxy response to auth method
$response = fread($socket, 2);
if ($response !== "\x05\x00" && (!$proxyAuth || $response !== "\x05\x02")) {
    echo "SOCKS5 auth method rejected" . PHP_EOL;
    fclose($socket);
    exit;
}

// If proxy requires auth, send username/password
if ($proxyAuth) {
    $userLen = strlen($proxyAuth['username']);
    $passLen = strlen($proxyAuth['password']);
    fwrite($socket, "\x01" . chr($userLen) . $proxyAuth['username'] . chr($passLen) . $proxyAuth['password']);
    $authResponse = fread($socket, 2);
    if ($authResponse !== "\x01\x00") {
        echo "SOCKS5 authentication failed" . PHP_EOL;
        fclose($socket);
        exit;
    }
}

// 3. Send target server address to proxy
// Format: SOCKS5 version (0x05), command (0x01 = connect), reserved (0x00), address type (0x03 = domain name)
$addrLen = strlen($ip);
fwrite($socket, "\x05\x01\x00\x03" . chr($addrLen) . $ip . pack('n', $port));

// Read proxy connection response
$connResponse = fread($socket, 10);
if ($connResponse[1] !== "\x00") {
    echo "SOCKS5 connection failed: error code " . ord($connResponse[1]) . PHP_EOL;
    fclose($socket);
    exit;
}

// 4. Now send your Minecraft packets as before
$data = "\x00";
$data .= makeVarInt($proto);
$data .= pack('c', strlen($ip)) . $ip;
$data .= pack('n', $port);
$data .= "\x02";
$handshake = pack('c', strlen($data)) . $data;
$nick = generateRandomString(5)."_RAGE_". generateRandomString(5);

// Send login handshake
fwrite($socket, $handshake);

// Send login initial packet
$data = "\x00";
$data .= pack('c', strlen($nick)) . $nick;
$data = pack('c', strlen($data)) . $data;
fwrite($socket, $data);

// Optional: Read server response
// $response = fread($socket, 4096);
// var_dump($response);

// Cleanup
// fclose($socket);

Option 2: Using an HTTP Proxy with CONNECT Tunneling

If you need to use an HTTP proxy, it must support the CONNECT method (which creates a TCP tunnel to the target server). Here's how to implement that:

Modified Code

// Proxy configuration
$proxyHost = 'your-http-proxy-ip';
$proxyPort = 8080; // Common HTTP proxy port
$proxyAuth = null; // Leave null if no auth, or use 'user:pass'

// Minecraft server details
$ip = 'mc.example.com';
$port = 25565;
$proto = 760;

// Your existing makeVarInt and generateRandomString functions here...

// 1. Connect to the HTTP proxy
$socket = @stream_socket_client("tcp://$proxyHost:$proxyPort", $errno, $errstr, 10);
if ($errno > 0) {
    echo "Proxy connection ERROR: " . $errstr . PHP_EOL;
    exit;
}

// 2. Send CONNECT request to create a tunnel
$connectRequest = "CONNECT $ip:$port HTTP/1.1\r\nHost: $ip:$port\r\n";
if ($proxyAuth) {
    $connectRequest .= "Proxy-Authorization: Basic " . base64_encode($proxyAuth) . "\r\n";
}
$connectRequest .= "\r\n";

fwrite($socket, $connectRequest);

// 3. Read proxy response to confirm tunnel is established
$response = fread($socket, 4096);
if (!strpos($response, '200 Connection established')) {
    echo "HTTP proxy tunnel failed: " . $response . PHP_EOL;
    fclose($socket);
    exit;
}

// 4. Send Minecraft packets as before (same as original code)
$data = "\x00";
$data .= makeVarInt($proto);
$data .= pack('c', strlen($ip)) . $ip;
$data .= pack('n', $port);
$data .= "\x02";
$handshake = pack('c', strlen($data)) . $data;
$nick = generateRandomString(5)."_RAGE_". generateRandomString(5);

fwrite($socket, $handshake);

$data = "\x00";
$data .= pack('c', strlen($nick)) . $nick;
$data = pack('c', strlen($data)) . $data;
fwrite($socket, $data);

// Optional: Read server response
// $response = fread($socket, 4096);
// var_dump($response);

// Cleanup
// fclose($socket);

Key Notes

  • SOCKS5 is preferred for Minecraft since it's purpose-built for raw TCP traffic, whereas HTTP proxies with CONNECT are more of a workaround.
  • Ensure your proxy allows traffic to Minecraft's default port (25565) or the custom port you're using.
  • Don't skip error handling for cases like proxy timeouts, authentication failures, or server unavailability.

内容的提问来源于stack exchange,提问作者Gett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:57:42