在PHP中,可以通过修改php.ini中的memory_limit指令来设置可用内存的大小。默认情况下,这个指令设置为128MB。

要更改此设置,请按照以下步骤操作:

1. 找到php.ini文件。这个文件通常在PHP安装的目录中。

2. 使用文本编辑器打开php.ini文件。

3. 找到以下行:

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M

4. 将memory_limit值更改为新大小,例如256M或512M。

5. 保存文件并重新启动PHP务器,以便更改生效。

请注意,如果您正在使用共享服务器,请先检查您是否有权更改此设置。一些虚拟主机提供商可能会限制您对php.ini文件的访问权限。

在 PHP 中获取 URL 参数可以通过 $_GET 超全局变量来实现。

例如,如果您想获取名为 id 的 URL 参数的值,可以使用以下代码:

$id = $_GET['id'];

如果 URL 中有多个参数,您可以通过类似的方式获取它们的值,例如:

$id = $_GET['id'];
$name = $_GET['name'];

请注意,$_GET 超全局变量仅能获取通过 GET 方法传递的参数,如果您使用 POST 方法传递参数,需要使用 $_POST 超全局变量或者 $_REQUEST 超全局变量获取参数。

以下是所有可用的 Nginx 编译参数列表:

--prefix=path                : 安装路径,默认为 /usr/local/nginx。
--sbin-path=path             : nginx 可执行文件的路径,默认为 prefix/sbin/nginx。
--conf-path=path             : nginx 配置文件的路径,默认为 prefix/conf/nginx.conf。
--error-log-path=path        : 错误日志文件的路径,默认为 prefix/logs/error.log。
--pid-path=path              : nginx 主进程 PID 文件的路径,默认为 prefix/logs/nginx.pid。
--lock-path=path             : nginx 锁文件的路径,默认为 prefix/logs/nginx.lock。
--user=name                  : 指定运行 nginx 的用户,默认为 nobody。
--group=name                 : 指定运行 nginx 的用户组,默认为 nobody。
--build=name                 : 指定编译环境,默认为当前主机的信息。
--builddir=path              : 指定编译时生成临时文件的目录,默认为 /tmp/nginx。
--with-select_module         : 启用 select 模块。
--without-select_module      : 禁用 select 模块。
--with-poll_module           : 启用 poll 模块。
--without-poll_module        : 禁用 poll 模块。
--with-threads               : 启用线程池。
--without-threads            : 禁用线程池。
--with-file-aio              : 启用文件异步 IO。
--with-http_ssl_module       : 启用 SSL/TLS 支持。
--without-http_ssl_module    : 禁用 SSL/TLS 支持。
--with-http_v2_module        : 启用 HTTP/2 支持。
--without-http_v2_module     : 禁用 HTTP/2 支持。
--with-http_realip_module    : 启用 realip 模块,用于获取真实客户端 IP。
--without-http_realip_module : 禁用 realip 模块。
--with-http_addition_module  : 启用 addition 模块,用于添加响应体。
--without-http_addition_module: 禁用 addition 模块。
--with-http_sub_module       : 启用 sub 模块,用于替换响应体。
--without-http_sub_module    : 禁用 sub 模块。
--with-http_dav_module       : 启用 dav 模块,用于 WebDAV 支持。
--without-http_dav_module    : 禁用 dav 模块。
--with-http_flv_module       : 启用 flv 模块,用于流媒体服务器。
--without-http_flv_module    : 禁用 flv 模块。
--with-http_mp4_module       : 启用 mp4 模块,用于流媒体服务器。
--without-http_mp4_module    : 禁用 mp4 模块。
--with-http_gunzip_module    : 启用 gunzip 模块,用于动态解压缩响应体。
--without-http_gunzip_module : 禁用 gunzip 模块。
--with-http_gzip_static_module : 启用 gzip_static 模块,用于预压缩静态文件。
--without-http_gzip_static_module : 禁用

一、问题描述:

用VSCode书写代码利用mysqli语句连接Mysql数据库的时候,没有出现智能提示:

二、原因:没有安装PHP Intelephense插件(注意有相似名字的插件不要安装错误)

三、安装:PHP Intelephense

打开VSCode编辑器,

(1)点击扩展;

(2)在打开的扩展商店中搜索“PHP Intelephense”;

(3)安装(下图为已经安装成功的截图);

四、配置:PHP Intelephense 插件:

打开VS Code编辑器,(1)点击左下角的小齿轮图标【管理】->(2)选择【命令面板】

(3)输入”settings.json”来搜索;点击【首选项:打开用户设置 (JSON)】即可进入用户设置settings.json文件

(4)配置:php.validate.executablePath路径(按自身情况填写,就是php.exe文件的路径),比如我的:”php.validate.executablePath”:

“D:\\phpstudy_pro\\Extensions\\php\\php7.3.4nts\\php.exe”

五、验证:插件使用效果

Rails is a full-stack framework.  It ships with all the tools needed to build amazing web apps on both the front and back end.

在 Rails 6 中有两种不同的工具可以用来管理前端的 CSS、JavaScript 以及 images 等资源,分别是 “Sprockets” 和 “Webpacker”,“Sprockets” 除了 Rails 应用外很少使用,但是 “Webpacker” 不仅在 Rails 中,在其他应用框架中也被广泛的使用。

在 Rails 7 中静态资源的管理已经从 “Webpacker” 改为了 “Import Maps”,用来简化基于 JavaScript 的工具和包管理器 Webpack、Yarn 或者 npm 的使用。

Rails 7 实现了一个愿景,即一种真正的全栈 Web 开发方式,可以同时应对前端和后端的挑战。

Rails 7.0: Fulffilling a vision

本文将使用 Ruby 3.0 和 Rails 7.0 环境,创建 Rails 7 应用,并在该应用中引入 Bootstrap 5。

第一种方式:仅引入 Bootstrap

创建 Rails 项目

首先使用 rails new 命令创建 Rails 项目:

如果创建项目的时间过长,可以考虑更换 Ruby 的 Gem 源,使用 RubyChina 的源:

# 删除国外源,使用 RubyChina 的源

gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/

安装 importmap

项目创建完成后进入项目目录,首先检查config目录下是否包含 “importmap.rb” 文件,如果没有可以通过 rails importmap 命令来安装:

cat config/importmap.rb



# 安装 importmap
rails importmap:install

添加 Bootstrap 5

# 在项目目录下执行 importmap 命令,安装 Bootstrap 5

bin/importmap pin bootstrap

该命令执行后会在 config/importmap.rb 中添加命令行中打印出的内容。

在安装 importmap 是创建的 app/javascript/application.js 文件中导入 ”bootstrap“:

// ...



// 新增内容

import 'bootstrap'



// ...

安装 Bootstrap 5 Ruby Gem

在 Gemfile 中新增如下内容:

# Gemfile

# ...

gem 'bootstrap', '~> 5.2.3'

# ...

保存后执行 bundle install 命令安装依赖。

application.scss 中导入 bootstrap

app/assets/stylesheets/application.css 重命名为app/assets/stylesheets/application.scss

# 更改文件后缀为 scss

mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss

增加内容:

// app/assets/stylesheets/application.scss

// ...



@import "bootstrap";



// ...

测试 Bootstrap

使用 rails g controller 命令创建一个 home_controller 以及 index 函数:

参考 Bootstrap Navabar 的样式修改 app/views/layouts/application.html.erb 页面

<!DOCTYPE html>

<html>

  <head>

    <title>RailsBootstrap</title>

    <meta name="viewport" content="width=device-width,initial-scale=1">

    <%= csrf\_meta\_tags %>

    <%= csp\_meta\_tag %>



    <%= stylesheet\_link\_tag "application", "data-turbo-track": "reload" %>

    <%= javascript\_importmap\_tags %>

  </head>



  <body>

    <header>

      <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">

        <div class="container-fluid">

          <a class="navbar-brand" href="#">Top navbar</a>

          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">

            <span class="navbar-toggler-icon"></span>

          </button>

          <div class="collapse navbar-collapse" id="navbarCollapse">

            <ul class="navbar-nav me-auto mb-2 mb-md-0">

              <li class="nav-item">

                <a class="nav-link active" aria-current="page" href="#">Home</a>

              </li>

              <li class="nav-item">

                <a class="nav-link" href="#">Link</a>

              </li>

              <li class="nav-item">

                <a class="nav-link disabled">Disabled</a>

              </li>

            </ul>

            <form class="d-flex" role="search">

              <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">

              <button class="btn btn-outline-success" type="submit">Search</button>

            </form>

          </div>

        </div>

      </nav>

    </header>

    <%= yield %>

  </body>

</html>

修改 app/views/home/index.html.erb 页面:

<div class="bg-light p-5 rounded">

  <h1>Navbar example</h1>

  <p class="lead">This example is a quick exercise to illustrate how the top-aligned navbar works. As you scroll, this navbar remains in its original position and moves with the rest of the page.</p>

  <a class="btn btn-lg btn-primary" href="/docs/components/navbar/" role="button">View navbar docs &raquo;</a>

</div>

通过 rails s 命令启动 Rails 应用,在浏览器中输入 localhost:3000/home/index 查看 index 页面

出现该页面说明引入的 Bootstrap 已经生效。

第二种方式:引入 Bootstrap 和 jQuery

添加 Bootstrap 和 jQuery 的 Ruby Gem

创建一个新的项目 rails-bootstrap-jquery,之后再项目的 Gemfile 中添加如下 Ruby Gems:

gem "sassc-rails"

gem "bootstrap", "~> 5.2.3"

gem "jquery-rails"

执行 bundle install 命令。

接着执行如下命令,修改application.css 后缀,创建 custom.css 以及 my_script.js 文件:

# 修改 application.css 为 application.scss

mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss

# 创建 custom.scss

touch app/assets/stylesheets/custom.scss

# 创建 my\_script.js

touch app/javascript/my\_script.js

在 application.scss 中添加如下内容:

@import "bootstrap";

@import "custom";

config/environments/development.rb 文件中添加如下内容:

config.sass.inline\_source\_maps = true

删除 tmp 文件夹下的缓存:

$ rm -r tmp/cache/assets

config/importmap.rb 文件中添加如下内容:

# From "jquery-rails" gem

pin "jquery", to: "jquery3.min.js", preload: true

pin "jquery\_ujs", to: "jquery\_ujs.js", preload: true



# From "bootstrap" gem

pin "bootstrap", to: "bootstrap.min.js", preload: true

pin "@popperjs/core", to: "popper.js", preload: true



# Custom JS

pin "my\_script", to: "my\_script.js", preload: true

config/initializers/assets.rb 中添加内容:

Rails.application.config.assets.precompile += %w( jquery3.min.js jquery\_ujs.js bootstrap.min.js popper.js )

app/javascript/application.js 中使用 import 关键字导入:

import "jquery";

import "jquery\_ujs";

import "@popperjs/core";

import "bootstrap";

import "my\_script";

app/javascript/my\_script.js 中添加如下 JS 代码:

document.addEventListener("turbo:load", () => {

  const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');

  const popoverList = [...popoverTriggerList].map((popoverTriggerEl) => new bootstrap.Popover(popoverTriggerEl));

});

app/assets/stylesheets/custom.scss 中添加如下样式:

.body-offset {

  margin-top: 50px;

}

测试 Bootstrap

创建一个 home_controller.rb

rails g controller home index

修改 app/views/layouts/application.html.erb Layout 布局:

<!DOCTYPE html>

<html>

  <head>

    <title>RailsBootstrapJquery</title>

    <meta name="viewport" content="width=device-width,initial-scale=1">

    <%= csrf\_meta\_tags %>

    <%= csp\_meta\_tag %>



    <%= stylesheet\_link\_tag "application", "data-turbo-track": "reload" %>

    <%= javascript\_importmap\_tags %>

  </head>



  <body>

    <header>

      <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">

        <div class="container-fluid">

          <a class="navbar-brand" href="#">Top navbar</a>

          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">

            <span class="navbar-toggler-icon"></span>

          </button>

          <div class="collapse navbar-collapse" id="navbarCollapse">

            <ul class="navbar-nav me-auto mb-2 mb-md-0">

              <li class="nav-item">

                <a class="nav-link active" aria-current="page" href="#">Home</a>

              </li>

              <li class="nav-item">

                <a class="nav-link" href="#">Link</a>

              </li>

              <li class="nav-item">

                <a class="nav-link disabled">Disabled</a>

              </li>

            </ul>

            <form class="d-flex" role="search">

              <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">

              <button class="btn btn-outline-success" type="submit">Search</button>

            </form>

          </div>

        </div>

      </nav>

    </header>

    <%= yield %>

  </body>

</html>

修改 app/views/home/index.html.erb 页面:

<div class="container">

  <div class="row">

    <div class="col-md-8 mt-4">

      <button type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" data-bs-title="Popover title" data-bs-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>

    </div>

  </div>



  <div class="row mt-4">

    <div class="col-md-8">

      <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Top popover">

        Popover on top

      </button>

      <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Right popover">

        Popover on right

      </button>

      <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Bottom popover">

        Popover on bottom

      </button>

      <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Left popover">

        Popover on left

      </button>

    </div>

  </div>

</div>

使用 rails s 启动 Rails 项目,查看 http://0.0.0.0:3000/home/index

此片文章主要参考CSDN博主里头的一篇文章, 将自己的理解写下来,以方便后期的查阅。

已知空间上若干点(xi, yi, zi), 求空间上包含这些点的最小球半径 R, 以及球心坐标。

思路:球心与这些点的最大距离为半径, 球心与最大距离点生成向量,将球心朝着该向量方向移动若干距离,再计算半径的变化。

namespace Test_BST
{
    public class Program
    {
        static void Main(string[] args)
        {
            // 初始化输入点
            List<Point> originPoints = new List<Point>() { ............};
            double radius = AnnealAlgorithm(originPoints);
        }

        private struct Point
        {
            public double x;
            public double y;
            public double z;
        }

        // square of a number
        private static double Sqr(double x) { return x * x; }

        // 两点之间的距离
        private static double Dist(Point A, Point B)
        {
            return Math.Sqrt(Sqr(A.x - B.x) + Sqr(A.y - B.y) + Sqr(A.z - B.z));
        }

        // 求最大半径
        private static double GetMaxRadius(Point p0, List<Point> pts)
        {
            double maxRadius = 0;
            foreach (var point in pts)
            {
                double radius = Dist(p0, point);
                maxRadius = radius > maxRadius ? radius : maxRadius;
            }

            return maxRadius;
        }

        private static double AnnealAlgorithm(List<Point> originPts)
        {
            Point center = new Point();
            center.x = 0;
            center.y = 0;
            center.z = 0;

            // 将初始化中心点设置为所有点的代数平均位置
            foreach (var pt in originPts)
            {
                center.x += pt.x;
                center.y += pt.y;
                center.z += pt.z;
            }
            center.x /= originPts.Count;
            center.y /= originPts.Count;
            center.z /= originPts.Count;

            double temp = 1e3; // 初始温度
            double coolingFactor = 0.98; // 降温因子
            double ans = GetMaxRadius(center, originPts); // 当前最小半径
            var random = new Random();

            while (temp > 1e-5)
            {
                Point newCenter = new Point();
                double max_r = 0;
                // 找到与当前中心点距离最远的点,将中心向着改点移动
                for (int i = 0; i < originPts.Count; i++)
                {
                    double r = Dist(center, originPts[i]);
                    if (r > max_r)
                    {
                        newCenter.x = (originPts[i].x - center.x) / r;
                        newCenter.y = (originPts[i].y - center.y) / r;
                        newCenter.z = (originPts[i].z - center.z) / r;
                        max_r = r;
                    }
                }
                newCenter.x = center.x + newCenter.x * temp;
                newCenter.y = center.y + newCenter.y * temp;
                newCenter.z = center.z + newCenter.z * temp;

                // 移动后的最大半径
                double tmp = GetMaxRadius(newCenter, originPts);

                if (tmp < ans) 
                {
                    center.x += newCenter.x * temp;
                    center.y += newCenter.y * temp;
                    center.z += newCenter.z * temp;
                }
                else if (Math.Exp((ans -tmp)/temp) > random.NextDouble() )
                {
                    center.x += newCenter.x * temp;
                    center.y += newCenter.y * temp;
                    center.z += newCenter.z * temp;
                }

                temp *= coolingFactor;
            }
            double miniRadius = GetMaxRadius(center, originPts);
            Console.WriteLine("the cooridnate of the center is {0}, the radius value is {1}", center, miniRadius));

            return miniRadius;
        }
    }
}

原文:http://blog.csdn.net/whai362/article/details/46980471#comments

前言

最近有些 MJJ 采集博客,使内存有些超标,看了下文件发现军哥的 LNMP 的php-fpm配置是按最低标准设置的,这里可以稍微修改下,适用于自己的 VPS 配置。

修改说明

php-fpm设置动态还是静态,要根据你的 VPS 内存来定,如果内存小,比如 1G,那么指定静态的进程数量更加有利于服务器的稳定。这样可以保证 php-fpm 只获取够用的内存,将不多的内存分配给其他应用去使用,会使系统的运行更加畅通。

如果你的内存足够大,例如 4G 或 4G 以上你可以将 pm 设置成静态(static),因为这样不需要进行额外的进程数目控制,会提高效率(频繁开关 php-fpm 进程也会有时滞的)所以内存够大的情况下开静态效果会更好。
比如 4GB 内存可以设置为pm.max_children = 80,那么按照每个进程占用 15~30M 内存计算,php-fpm 耗费的内存就能控制在 1.2G-2.5G 的样子。

这里主要修改几个参数,说明一下:

  • pm.max_children:静态方式下开启的 php-fpm 进程数量;
  • pm.start_servers:动态方式下的起始 php-fpm 进程数量;
  • pm.min_spare_servers:动态方式下的最小备用 php-fpm 进程数量;
  • pm.max_spare_servers:动态方式下的最大备用 php-fpm 进程数量;

这里是军哥 LNMP 的/usr/local/php/etc/php-fpm.conf默认 1G 配置,LNMP 也会根据内存大小安装后配置不同,仅用于参考

pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 6
pm.max_requests = 1024
pm.process_idle_timeout = 10s
request_terminate_timeout = 100
request_slowlog_timeout = 0
slowlog = var/log/slow.log

博主的机器是 1G 内存,修改后的配置可以参考,具体参数要设多少,可自己慢慢测试

pm = dynamic
pm.max_children = 24
pm.start_servers = 6
pm.min_spare_servers = 3
pm.max_spare_servers = 9
pm.max_requests = 2048
pm.process_idle_timeout = 10s
request_terminate_timeout = 120
request_slowlog_timeout = 0
slowlog = var/log/slow.log

结语

博主在使用pm = dynamic,  有时日志(/usr/local/php/var/log/php-fpm.log)里提示  pm.max_children  过小,  调大  pm.max_children  值, 日志里的 pm.max_children  警告就没有了。

DNS

简介

域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换,以及控制因特网的电子邮件的发送。

(首先需要打开阿里云官方镜像站:https://developer.aliyun.com/mirror/ 找到DNS服务器地址,再进行后续操作。)

Chrome浏览器配置方法

第一步:打开Chrome浏览器,从菜单栏中点击【设置】选项。

第二步:在搜索框中输入“DNS”,在下方的检索结果中,点击【安全】右侧的展开箭头。

第三步:页面下拉到最下方,在【高级】选项中,开通“使用安全DNS”功能,并在【使用】-【自定义】框中输入“ https://dns.alidns.com/dns-query ”即可完成配置。

示例

以下示例演示如何使用 TransactionScope 类定义代码块以参与事务。


C#

复制
// This function takes arguments for 2 connection strings and commands to create a transaction 
// involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the 
// transaction is rolled back. To test this code, you can connect to two different databases 
// on the same server by altering the connection string, or to another 3rd party RDBMS by 
// altering the code in the connection2 code block.
static public int CreateTransactionScope(
    string connectString1, string connectString2,
    string commandText1, string commandText2)
{
    // Initialize the return value to zero and create a StringWriter to display results.
    int returnValue = 0;
    System.IO.StringWriter writer = new System.IO.StringWriter();

    try
    {
        // Create the TransactionScope to execute the commands, guaranteeing
        // that both commands can commit or roll back as a single unit of work.
        using (TransactionScope scope = new TransactionScope())
        {
            using (SqlConnection connection1 = new SqlConnection(connectString1))
            {
                // Opening the connection automatically enlists it in the 
                // TransactionScope as a lightweight transaction.
                connection1.Open();

                // Create the SqlCommand object and execute the first command.
                SqlCommand command1 = new SqlCommand(commandText1, connection1);
                returnValue = command1.ExecuteNonQuery();
                writer.WriteLine("Rows to be affected by command1: {0}", returnValue);

                // If you get here, this means that command1 succeeded. By nesting
                // the using block for connection2 inside that of connection1, you
                // conserve server and network resources as connection2 is opened
                // only when there is a chance that the transaction can commit.   
                using (SqlConnection connection2 = new SqlConnection(connectString2))
                {
                    // The transaction is escalated to a full distributed
                    // transaction when connection2 is opened.
                    connection2.Open();

                    // Execute the second command in the second database.
                    returnValue = 0;
                    SqlCommand command2 = new SqlCommand(commandText2, connection2);
                    returnValue = command2.ExecuteNonQuery();
                    writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
                }
            }

            // The Complete method commits the transaction. If an exception has been thrown,
            // Complete is not  called and the transaction is rolled back.
            scope.Complete();
        }
    }
    catch (TransactionAbortedException ex)
    {
        writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message);
    }

    // Display messages.
    Console.WriteLine(writer.ToString());

    return returnValue;
}

注解

如果确信范围内的所有操作都已成功完成,则只应调用此方法一次,以通知事务管理器所有资源的状态都是一致的,并且可以提交事务。 最好将调用作为块中的 using 最后一个语句。

未能调用此方法会中止事务,因为事务管理器将此解释为系统故障或在事务范围内引发的异常。 但是,还应注意,调用此方法并不能保证事务的提交。 它只是一种将状态通知给事务管理器的方式。 调用此方法后,无法再通过 Current 属性访问环境事务,并且尝试这样做会导致引发异常。

如果 TransactionScope 对象创建了事务,则资源管理器之间的实际提交工作将发生在 End Using 语句中。 如果该对象未创建事务,则每当 Commit 对象的所有者调用 CommittableTransaction 时都会执行提交。 此时,事务管理器会调用资源管理器,并根据是否在 对象上 TransactionScope 调用此方法来通知它们提交或回滚。

在Windows系统中,从XP开始就内嵌了一个设置网络端口转发的功能。依靠这个功能,任何到本地端口的TCP连接(ipv4或ipv6)都能够被转发到任意一个本地端口,甚至是远程主机的某个端口。并且,Windows系统并不需要去开启监听这个转发端口的服务。

在Windows服务器中,远程访问控制协议(RRAS)通常被用作端口转发,但是有一种更简单的配置方法,并且这种配置方法适用于windows的任意版本。

Windows系统下的端口转发使用portproxy模式下的netsh命令,该命令的使用前提是要在管理员身份打开cmd进行执行。

netsh interface portproxy add v4tov4  listenaddress=localaddress listenport= localport connectaddress=destaddress  connectport=destport protocol=tcp

listenaddress – 待连接的ip地址。

listenport –待连接的tcp本地端口 。

connectaddress – 待连接被转发的本地或远程主机的ip地址(支持域名)

connectport –从listenport转发到的tcp端口

案例

将一个RDP服务(远程桌面协议)转发到任意端口,将进来的流量从3340端口转发到标准的RDP端口3389。

netsh interface portproxy add v4tov4  listenport=3340 listenaddress=10.1.1.110  connectport=3389 connectaddress=10.1.1.110

1) netstat -ano | findstr :3340来验证3340端口是否正在监听中,如果该命令没有返回任何信息,或者说通过netsh接口并没有实现端口转发的功能,那么需要查看下系统是否开启了iphlpsvc(ip Helper)服务。

2) tasklist | findstr 3340查看监听该端口的进程

3) 检查防火墙是否关闭,如果关闭则跳过。如果打开需要手工配置相应的防火墙。

连接时请确保防火墙(Windows防火墙或者其他的第三方防护软件)允许外部连接到一个全新的端口,如果不允许,那么只能自行添加一个新的Windows防火墙规则,命令如下:netsh advfirewall firewall add rule name=”forwarded_RDPport_3340”  protocol=TCP dir=in localip=10.1.1.110  localport=3340 action=allow

当通过Windows防火墙接口为3340端口建立一个新的规则时,这个端口需要保证没有被任何程序占用,也就是说此端口仅供网络驱动使用。你可以创立任意的Windows端口转发规则,所有的netsh接口下的端口代理规则都是永久的,并且储存在系统中(不受开机重启的影响)。

查看系统中的所有转发规则是否生效:

netsh interface portproxy show all

查看端口转发的设置:netsh interface portproxy dump

删掉一个特定的端口转发规则:

netsh interface portproxy delete v4tov4

清空当前所有的配置规则:

netsh interface portproxy reset

从远程主机来尝试连接这个新转发的端口3340,3340端口等同于原来的3389端口,连接的地址为10.10.1.110:3340。

注意:这些转发规则仅仅适用于TCP端口,对于UDP的端口转发,使用上面的方法是无效的。在配置规则时,不能将127.0.0.1作为连接地址。

其他端口转发招式

1) 通过一台windows机器端口转发到一台windows远程主机

netsh interface portproxy add v4tov4  listenport=3340 listenaddress=10.1.1.110  connectport=3389  connectaddress=10.1.1.110

netsh interface portproxy add v4tov4 listenport=3389 listenaddress=0.0.0.0 connectport=3389 connectaddress=192.168.100.101

2) 通过一台ipv4的Windows机器转发到一台ipv6的服务器。

netsh interface portproxy add v4tov6  listenport=3340 listenaddress=10.1.1.110  connectport=3389  connectaddress=ffff::66

FAQ

1) 在Windows Server 2012 R2中,端口转发规则有可能会在系统重启后被重置,在这种情况下,需要在网络协议中检查是否存在配置不当,导致网络的间断性断开,或者当系统重启时是否出现了ip地址的变换(推荐使用静态ip)。在一个工作组里,通常是在windows任务计划程序里添加了一个实现端口转发的脚本。

2) 在Windows 2003/XP中,必须在注册表(HKLM\SYSTEM\ControlSet001\Services\Tcpip\Parameters)中找到并设置IPEnableRouter参数为1才能实现端口转发。

3) 防火墙规则检查

4) 端口转发依赖的ip helper服务是否启动

5) 端口转发是否生效

Windows日志查看

6273 网络策略服务器拒绝用户访问。

6274 网络策略服务器放弃用户的请求。

4868 证书管理器拒绝了挂起的证书请求。

4870 证书服务吊销了证书。

4944 当启动 Windows 防火墙时,以下策略处于活动状态。

4945 当启动 Windows 防火墙已列出规则。

4946 Windows 防火墙例外列表已更改。添加的规则。

4947 Windows 防火墙例外列表已更改。修改规则的。

4948 Windows 防火墙例外列表已更改。规则已被删除。

4949 Windows 防火墙设置都恢复为默认值。

4950 更改 Windows 防火墙设置。

4951 Windows 防火墙忽略规则,因为无法识别的主要版本号。

4952 Windows 防火墙忽略规则的部分,因为无法识别它的次要版本号。将强制执行该规则的其他部分。

4953 由于无法分析,Windows 防火墙将忽略规则。

4954 Windows 防火墙组策略设置已更改,并且未应用新设置。

4956 Windows 防火墙更改活动配置文件。

5024 Windows 防火墙服务已成功启动。

5025 Windows 防火墙服务已停止。

5027 Windows 防火墙服务无法从本地存储区中检索的安全策略。Windows 防火墙将继续执行当前的策略。

5028 Windows 防火墙无法分析新的安全策略。Windows 防火墙将继续执行当前的策略。