Socks5 プロキシ サーバーを実装するための 100 行の PHP コードへの毎日の挑戦
2 日前、ステーション B で、スムーズな画質で LOL をプレイするためにコンピューターを 100 元で組み立てようとしている人を見て、100 行のコードで (単純に) 何か楽しいことが実現できるのではないかと突然思いました。私は主にPHP開発を行っているので、この記事を書いています。
もちろん、PHP (swoole 拡張機能は除く) 自体はネットワーク サーバー プログラミングが得意ではないため、このプロキシは単なるおもちゃであり、日常的な使用からは少し離れています。安定した信頼性の高い暗号化 (インターネットサーフィンを学習できるように) プロキシを使用したい場合は、これを使用できます: https://github.com/momaer/asocks-go これは、100 行の go を使用して実装することもできます。コード。
書いている過程で、PHP のマルチスレッドはまだ難しいことがわかりました。たとえば、接続ごとに新しいスレッドを作成したいと思うようになりました。ただし、このスレッドは保存する必要があります (たとえば、配列に保存する)。たとえば、公式の例では https://github.com/krakjoe/pthreads/blob/master/examples/SocketServer.php を次のように配置する必要があります。それ以外の場合は、(curl -L 301 を必要とするアドレス) を試してみると、何が起こるかわかります。
この例は、現実の世界では、実行されていないクライアントが確実に破棄されるように何かを行うことを示していますが、実行されなくなった接続を破棄する方法については説明しません。親切。 $clients をクラスに入れ、そのクラスをスレッド クラスに渡し、スレッド クラスが終了しようとしたときに $clients 内の対応する接続の設定を解除しようとしましたが、無駄でした。
次に、以下はスレッド プールを使用して実装されたプロキシです。論理的に言えば、終了時にプールを shutdown() する必要があり、監視ソケットもシャットダウンする必要があります。しかし、100 行のコードでは、その必要はありません。 Ctrl + C を押すと、オペレーティング システムにリソースを再利用させます。
PHP はなぜネットワーク プログラミングが苦手なのでしょうか?まずはストリームsocketXXX関連の関数を使ってみました ソケット拡張を使ってみませんか?ソケット拡張機能に問題があるため、https://github.com/krakjoe/pthreads/issues/581 を参照してください。また、ストリーム settimeout は、ストリーム Socketrecvfrom などの高度な操作では機能しません。http://php.net を参照してください。 /manual/en /function.stream-set-timeout.php プロキシを作成するときは、これらを考慮する必要があります。たとえば、リモートのターゲット サーバーに接続する場合、タイムアウト制御がないため、スレッド プールが簡単にいっぱいになる可能性があります。
テストするには、curl を使用してください。 ちなみに、現在はリモート DNS 解決のみがサポートされています。このおもちゃは後でインターネットにアクセスするために使用されるため、次のようになります。 function _construct($client, $remote) { $this->client = $client; $this->remote = $remote; } public function run() { for ( ; ; ) { $data = streamsocket recvfrom( $this->client, 4096); if ($data === false || strlen($data) === 0) { ブレーク; } $sendBytes = streamsocket sendto($this->remote, $ data) ; if ($sendBytes<= 0) { Break; } } stream_socket_shutdown($this->client, STREAMSHUT RD);
クラス クライアントは、スレッド化された { 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 '协议不正确.', 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 '请使用远程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 function __construct($pipePool) { $this->パイププール = $pipePool; } }
$server = ストリームソケットサーバー('tcp://0.0.0.0:1080', $errno, $errstr); if ($server === false)
$pipePool = 新しいプール(200, Worker::class); $pool = 新しいプール(50, 'ProxyWorker', [$pipePool]);
for( ; ; ) { $fd = @streamソケットaccept( $server , 60); if ($fd === false) $pool->submit(new Client($fd)) } ```

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。
