激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - 100行PHP代碼實(shí)現(xiàn)socks5代理服務(wù)器

100行PHP代碼實(shí)現(xiàn)socks5代理服務(wù)器

2021-01-13 16:59秣馬兒 PHP教程

這個(gè)例子說了in the real world, do something here to ensure clients not running are destroyed 但是,如何把不再運(yùn)行的連接銷毀卻沒有講。恩。我試了把$clients放到一個(gè)類里,把類傳給線程類,然后在線程類要結(jié)束時(shí)把$clients里對(duì)應(yīng)的連接給unset掉,

前兩天在B站上看到一個(gè)小伙紙100元組裝個(gè)電腦打LOL畫質(zhì)流暢,突發(fā)奇想100行代碼能(簡(jiǎn)單)實(shí)現(xiàn)個(gè)啥好玩的。我主要是做php開發(fā)的,于是就有了本文。

當(dāng)然,由于php(不算swoole擴(kuò)展)本身不擅長做網(wǎng)絡(luò)服務(wù)端編程,所以這個(gè)代理,只是個(gè)玩具,離日常使用有點(diǎn)距離。如果想使用穩(wěn)定可靠的加密(所以能禾斗學(xué)上網(wǎng))代理,可以用這個(gè):https://github.com/momaer/asocks-go也是100來行代碼使用go實(shí)現(xiàn)。

寫的過程中發(fā)現(xiàn)php多線程還是難的。比如我開始想每個(gè)連接新建一個(gè)線程。但這個(gè)線程得保存起來(比如保存到數(shù)組),比如官方例子中的這個(gè):https://github.com/krakjoe/pthreads/blob/master/examples/SocketServer.php 要放到$clients這個(gè)數(shù)組里,不然,你試試(curl -L一個(gè)要301的地址)就知道出現(xiàn)什么情況了。

這個(gè)例子說了in the real world, do something here to ensure clients not running are destroyed 但是,如何把不再運(yùn)行的連接銷毀卻沒有講。恩。我試了把$clients放到一個(gè)類里,把類傳給線程類,然后在線程類要結(jié)束時(shí)把$clients里對(duì)應(yīng)的連接給unset掉,無果。

那,以下就是使用線程池來實(shí)現(xiàn)的代理,按道理講,退出時(shí)池要shutdown(),監(jiān)聽socket也要shutdown的,但百行代碼,就不勉強(qiáng)了,隨著ctrl + c,就讓操作系統(tǒng)來回收資源吧。

php不擅長網(wǎng)絡(luò)編程體現(xiàn)在哪里呢?首先我用的是stream_socket_XXX相關(guān)的函數(shù),為啥不用socket擴(kuò)展呢?因?yàn)閟ocket擴(kuò)展有問題,參見:https://github.com/krakjoe/pthreads/issues/581 而stream_set_timeout對(duì)stream_socket_recvfrom這些高級(jí)操作,不起作用,參見:http://php.net/manual/en/function.stream-set-timeout.php 而這些,在寫代理時(shí)都需要考慮的。比如連接遠(yuǎn)程目標(biāo)服務(wù)器時(shí),沒有超時(shí)控制,很容易就線程池跑滿了。

測(cè)試的話,使用curl即可,對(duì)了,目前只支持遠(yuǎn)程dns解析,為啥呢?因?yàn)檫@個(gè)玩具后期可是要實(shí)現(xiàn)禾斗學(xué)上網(wǎng)的喲: curl --socks5-hostname 127.0.0.1:1080 http://ip.cn

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Class Pipe extends Threaded
{
  private $client;
  private $remote;
  public function __construct($client, $remote)
  {
    $this->client = $client;
    $this->remote = $remote;
  }
  public function run()
  {
    for ( ; ; ) {
        $data = stream_socket_recvfrom($this->client, 4096);
        if ($data === false || strlen($data) === 0) {
          break;
        }
        $sendBytes = stream_socket_sendto($this->remote, $data);
        if ($sendBytes <= 0) {
          break;
        }
    }
    stream_socket_shutdown($this->client, STREAM_SHUT_RD);
    stream_socket_shutdown($this->remote, STREAM_SHUT_WR);
  }
}
 
Class Client extends Threaded
{
  public $fd;
  public function __construct($fd)
  {
    $this->fd = $fd;
  }
 
  public function run()
  {
    $data = stream_socket_recvfrom($this->fd, 2);
    $data = unpack('c*', $data);
    if ($data[1] !== 0x05) {
      stream_socket_shutdown($this->fd, STREAM_SHUT_RDWR);
      echo '協(xié)議不正確.', PHP_EOL;
      return;
    }
    $nmethods = $data[2];
    $data = stream_socket_recvfrom($this->fd, $nmethods);
    stream_socket_sendto($this->fd, "\x05\x00");
    $data = stream_socket_recvfrom($this->fd, 4);
    $data = unpack('c*', $data);
    $addressType = $data[4];
    if ($addressType === 0x03) { // domain
      $domainLength = unpack('c', stream_socket_recvfrom($this->fd, 1))[1];
      $data = stream_socket_recvfrom($this->fd, $domainLength + 2);
      $domain = substr($data, 0, $domainLength);
      $port = unpack("n", substr($data, -2))[1];
    } else {
      stream_socket_shutdown($this->fd, STREAM_SHUT_RDWR);
      echo '請(qǐng)使用遠(yuǎn)程dns解析.', PHP_EOL;
    }
 
    stream_socket_sendto($this->fd, "\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00");
    echo "{$domain}:{$port}", PHP_EOL;
    $remote = stream_socket_client("tcp://{$domain}:{$port}");
    if ($remote === false) {
      stream_socket_shutdown($this->fd, STREAM_SHUT_RDWR);
      return;
    }
 
    $pool = $this->worker->pipePool;
 
    $pipe1 = new Pipe($remote, $this->fd);
    $pipe2 = new Pipe($this->fd, $remote);
 
    $pool->submit($pipe1);
    $pool->submit($pipe2);
  }
}
 
class ProxyWorker extends Worker
{
  public $pipePool;
  public function __construct($pipePool)
  {
    $this->pipePool = $pipePool;
  }
}
 
$server = stream_socket_server('tcp://0.0.0.0:1080', $errno, $errstr);
if ($server === false)
  exit($errstr);
 
$pipePool = new Pool(200, Worker::class);
$pool = new Pool(50, 'ProxyWorker', [$pipePool]);
 
for( ; ; ) {
  $fd = @stream_socket_accept($server, 60);
  if ($fd === false)
    continue;
  $pool->submit(new Client($fd));
}

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费毛片视频播放 | 羞羞视频一区二区 | xxxxxx免费| 欧美一级无毛 | 青青草华人在线 | 国产羞羞视频免费在线观看 | 日本欧美一区二区三区在线观看 | 国产91对白叫床清晰播放 | 国产做爰全免费的视频黑人 | 视频一区二区国产 | 久久久av影视 | 毛片免费大全短视频 | 超碰97人人艹 | 国产资源在线免费观看 | 国产一级片91 | 免费a视频在线观看 | 精品999www | 黄色网址进入 | 美国人成人在线视频 | 日日噜噜噜噜久久久精品毛片 | 午夜性久久 | 国产欧美日韩在线不卡第一页 | 欧美性生活久久久 | 91精品国产福利尤物免费 | 欧美在线观看19 | 久产久精品 | 在线成人免费av | sesee99| 亚洲成人高清在线观看 | 黄色av电影在线播放 | 深夜免费视频 | 久久经典视频 | 亚洲成人免费视频在线 | 免费看一级片 | 成人羞羞在线观看网站 | 狠狠操电影 | 黄色片免费在线播放 | 国产精品一区在线看 | 成人精品aaaa网站 | 欧美日韩亚洲国产精品 | 欧美一区二区三区成人 |