代码如下,php版本7.4.28
我用原生代码写了一个服务端和一个客户端,
服务端是 192.168.3.66 的 3306
客户端连接的 110.242.68.4:80 ,这个就是百度网站的地址
客户端作为服务器的代理工具,做数据转发。
要达到的效果就是 浏览器访问192.168.3.66的3306 等于访问110.242.68.4:80
现在的情况是,如果我在命令行使用nc来访问
nc 192.168.3.66 3306
GET / HTTP/1.1
然后是有正常的返回的。
但是如果用浏览器访问 http://192.168.3.66:3306
网页是不能正常展示的。
请朋友帮我看一下,问题是出在哪里了
<?php
class client
{
public $client ;
public $status;
public $client_id;
public $event=[];
public function on($name, $callBack)
{
$this->event[$name] = $callBack;
}
public function runEvent($eventName, $args)
{
if (is_callable($this->event[$eventName])) {
$this->event[$eventName]($this, ...$args);
}
}
public function __construct($host,$port)
{
$this->client = socket_create(AF_INET, SOCK_STREAM, 0);
$tag = socket_connect($this->client, $host,$port);
$this->client_id = (int) $this->client;
if($tag){
$this->status = 'run';
socket_set_nonblock($this->client);
}else{
die;
}
}
public function write($data)
{
socket_write($this->client, $data, strlen($data));
}
public function read()
{
$len_read = socket_recv($this->client, $string_read, 1024, 0);
if ($len_read === false) {
} elseif ($len_read === 0) {
socket_close($this->client);
// socket closed
$this->status = 'close';
$this->client= null;
$this->runEvent("close",[]);
} else {
$this->runEvent("message", [ $string_read]);
}
}
public function start()
{
$this->runEvent("connect",[]);
}
}
class Server
{
public $address;
public $mainSocket;
public $event;
public static $clients = [];
public $proxy_list = [];
public function __construct($address, $port)
{
$this->address = $address . ':' . $port;
$this->mainSocket = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($this->mainSocket, $address, $port);
socket_listen($this->mainSocket, 1);
socket_set_nonblock($this->mainSocket);
}
public function on($name, $callBack)
{
$this->event[$name] = $callBack;
}
public function runEvent($eventName, $args)
{
if (is_callable($this->event[$eventName])) {
$this->event[$eventName]($this, ...$args);
}
}
public function accept()
{
$clientFd = socket_accept($this->mainSocket);
if (is_resource($clientFd)) {
socket_set_nonblock($clientFd);
$client_id = (int) $clientFd;
self::$clients[$client_id] = $clientFd;
$this->runEvent("connect", [$clientFd]);
}
}
public function write($client, $data)
{
socket_write($client, $data, strlen($data));
}
public function read($client)
{
$id = (int) $client;
$len_read = socket_recv($client, $string_read, 1024, 0);
if ($len_read === false) {
} elseif ($len_read === 0) {
socket_close($client);
// socket closed
unset(self::$clients[$id]);
$this->runEvent("close", [$id]);
} else {
$this->runEvent("message", [$client, $string_read]);
}
}
public function start()
{
while (1) {
usleep(1000);
$read = [$this->mainSocket];
foreach (self::$clients as $client) {
$read[] = $client;
}
$write = [];
$error = [];
socket_select($read, $write, $error, 1);
if (count($read)) {
foreach ($read as $readFd) {
if ($readFd == $this->mainSocket) {
$this->accept();
} else {
$this->read($readFd);
}
}
}
if (count($this->proxy_list)) {
$read = [];
foreach ($this->proxy_list as $client) {
$read[] = $client->client;
}
$write = [];
$error = [];
socket_select($read, $write, $error, 1);
if (count($read)) {
foreach ($read as $readFd) {
$proxy_id = (int) $readFd;
$this->proxy_list[$proxy_id]->read();
}
}
}
}
}
}
$server = new Server('192.168.3.66', '3306');
$server->on('connect', function ($server, $client) {
// 110.242.68.4:80 这个是百度的网页
// 要达到的效果就是 访问192.168.3.66的3306 等于访问110.242.68.4:80
$client2 = new client('110.242.68.4', '80');
$server->proxy_list[$client2->client_id] = $client2;
$client2->on('connect', function ($client2) {
});
$client2->on('message', function ($client2, $data) use ($server, $client) {
$data = strtr($data, ['Host: 110.242.68.4:80' => 'Host: 192.168.3.66:3306']);
$server->write($client, $data);
});
$client2->on('close', function ($client2) use ($server, $client) {
unset($server->proxy_list[$client2->client_id]);
});
$server->on('message', function ($server, $client, $data) use ($client2) {
$data = strtr($data, ['Host: 192.168.3.66:3306' => 'Host: 110.242.68.4:80']);
$client2->write($data);
});
$server->on('close', function ($server, $id) {
});
$client2->start();
});
$server->start();