100 Multi-line PHP code implementation SOCKS5 Proxy Server [2]_php instance

Source: Internet
Author: User
Tags php class strlen unpack
More than 100 lines of PHP code to implement SOCKS5 proxy server, this time using Swoole pure asynchronous to write, using the state machine to process data. Currently using it to access open source Chinese wood is stressful, but visit NetEase news on the pressure of Alexander. I found that I write in other languages agent, access to NetEase news are very stressful. Quack, the Apprentice is not fine.

Not deep understanding of swoole, do not know how to handle the socket shutdown only close read/write So, there is the connection timeout, read and write timeout this how to deal with. On the Internet to see the author said to use the timer, feel good trouble, so, this time the agent, although the personal use, generally will not have any problems, but the agent from the product level, there are a section of the road to go.

If you want to take advantage of multi-core, use process mode, set the number of worker as the number of CPUs.

<?php class Client {public $connected = true;
 Public $data = ';
 public $remote = null;
Public $status = 0;
 Class Server {public $clients = [];
  The 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_no
  Delay ' => 1, ' log_file ' => ' socks5_server.log ',];
  $server->on (' Connect ', [$this, ' onConnect ']);
  $server->on (' Receive ', [$this, ' onreceive ']);
  $server->on (' Close ', [$this, ' onClose ']);
 $server->start ();
 The Public Function OnConnect ($server, $FD, $fromID) {$this->clients[$fd] = new Client ();
  The Public function onreceive ($server, $FD, $fromID, $data) {($this->clients[$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 is 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) {//Domain $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);
     else {echo ' Unsupported atype: '. $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\x0
     1\x00\x00\x00\x00\x00\x00 ");
     $client->status = 2;
    $client->remote = $remote;
    }); $remote->on ("Error", function (swoole_client $cli) use ($server, $FD) {//$server->send ($FD, ""); TODO connection not 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 host is empty.
       Seemingly nonexistent domain names are resolved to the local network IP, 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 = '; ->start ()}}} (new Server ());

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.