More than 100 lines of PHP code to implement the socks5 Proxy Server [2], phpsocks5

Source: Internet
Author: User

More than 100 lines of PHP code to implement the socks5 Proxy Server [2], phpsocks5
Over 100 lines of PHP code are used to implement the socks5 Proxy Server. This time, swoole is used for pure asynchronous writing and the state machine is used to process data. Currently, it is under pressure to access open source China wood, but it is under great pressure to access Netease news. I found that I wrote proxies in other languages, and it was a lot of pressure to access Netease news. Ga ga, learning is not refined.

I don't know much about swoole. I don't know how to handle socket shutdown. I only close reading/writing, and how to handle connection timeout and read/write timeout. I can see on the Internet that it is troublesome to use the timer. So, although I am using the proxy for this time, there is usually no problem, but there is still some way to go from the product-level proxy.

To use multiple cores, use the process mode and set the number of workers to the number of CPUs.

<? Phpclass Client {public $ connected = true; public $ data = ''; public $ remote = null; public $ status = 0;} class Server {public $ clients = []; public function start () {$ server = new swoole_server ('0. 0.0.0 ', 8388, SWOOLE_BASE, SWOOLE_SOCK_TCP); $ server-> set (['max _ conn' => 1000, 'daemonize' => 1, 'reactor _ num' => 1, 'worker _ num' => 1, 'dispatch _ mode' => 2, 'buffer _ output_size '=> 128*1024*1024,' Open_cpu_affinity '=> 1, 'open _ tcp_nodelay' => 1, 'Log _ file' => 's5 S5 _ server. log',]); $ server-> on ('connect ', [$ this, 'onconnect']); $ server-> on ('receive ', [$ this, 'onreceive ']); $ server-> on ('close', [$ this, 'onclose']); $ server-> start ();} public function onConnect ($ server, $ fd, $ fromID) {$ this-> clients [$ fd] = new Client ();} public function onReceive ($ server, $ fd, $ fromID, $ data) {($ this-> cl Ients [$ fd])-> data. = $ data; $ this-> parse ($ server, $ fd);} public function onClose ($ server, $ fd, $ fromID) {$ client = $ this-> clients [$ fd]; $ client-> connected = false;} private function parse ($ server, $ fd) {$ client = $ this-> clients [$ fd]; switch ($ client-> status) {case 0: {if (strlen ($ client-> data)> = 2) {$ request = unpack ('C * ', substr ($ client-> data, 0, 2); if ($ request [1]! = 0x05) {echo 'Protocol incorrect :'. $ request [1], PHP_EOL; $ server-> close ($ fd); break;} $ nmethods = $ request [2]; if (strlen ($ client-> data) >=2 + $ nmethods) {$ client-> data = substr ($ client-> data, 2 + $ nmethods ); $ server-> send ($ fd, "\ x05 \ x00"); $ client-> status = 1 ;}} case 1: {if (strlen ($ client-> data) <5) break; $ request = unpack ('C * ', $ client-> data ); $ aType = $ request [4]; if ($ aType = 0x03) {// do Main $ domainLen = $ request [5]; if (strlen ($ client-> data) <5 + $ domainLen + 2) {break ;} $ domain = substr ($ client-> data, 5, $ domainLen); $ port = unpack ('n', substr ($ client-> data, 5 + $ domainLen, 2) [1]; $ client-> data = substr ($ client-> data, 5 + $ domainLen + 2 );} else if ($ aType = 0x01) {// ipv4 $ domain = long2ip (unpack ('n', substr ($ client-> data, 4, 4 )) [1]); $ port = unpack ('n', substr ($ client-> Data, 8, 2) [1]; $ client-> data = substr ($ client-> data, 10);} atype not supported by else {echo: '. $ aType, PHP_EOL; $ server-> close ($ fd); break;} $ remote = new swoole_client (SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); $ remote-> on ('connect ', function ($ cli) use ($ client, $ server, $ fd, $ remote) {$ server-> send ($ fd, "\ x05 \ x00 \ x00 \ x01 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00"); $ client-> status = 2; $ client-> remote = $ remote;}); $ remot E-> on ("error", function (swoole_client $ cli) use ($ server, $ fd) {// $ server-> send ($ fd ,""); // todo cannot connect to remote echo 'connect to remote error. ', PHP_EOL; $ server-> close ($ fd) ;}); $ remote-> on ('receive', function ($ cli, $ data) use ($ server, $ fd, $ client) {if (! $ Client-> connected) {echo 'Connection has been closed. ', PHP_EOL; return ;}$ server-> send ($ fd, $ data) ;}); $ remote-> on ('close', function ($ cli) use ($ server, $ fd, $ client) {$ client-> remote = null;}); if ($ aType = 0x03) {swoole_async_dns_lookup ($ domain, function ($ host, $ ip) use ($ remote, $ port, $ server, $ fd) {// todo processing when the host is empty. It seems that non-existing domain names are resolved to the local Internet ip address, strange if (empty ($ ip) | empty ($ host) {echo "host :{$ host}, ip: {$ ip} \ n "; $ server-> close ($ fd); return ;}$ remote-> connect ($ ip, $ port );});} else {$ remote-> connect ($ domain, $ port) ;}} case 2: {if (strlen ($ client-> data) === 0) {break ;} if ($ client-> remote === null) {echo 'remote connection has been closed. ', PHP_EOL; break;} $ sendByteCount = $ client-> remote-> send ($ client-> data ); if ($ sendByteCount = false | $ sendByteCount <strlen ($ client-> data) {echo 'data length: ', strlen ($ client-> data ), 'Send byte count: ', $ sendByteCount, PHP_EOL; echo $ client-> data, PHP_EOL; $ server-> close ($ fd );} $ client-> data = '';}}} (new Server ()-> start ();

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.