如何在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
- Connect to your SOCKS5 proxy instead of the Minecraft server directly.
- Complete the SOCKS5 handshake to inform the proxy of your target Minecraft server's address and port.
- 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
相关产品推荐
相关产品推荐

