PHP 进展统一邮箱登陆的代理实现(swoole)
PHP 进行统一邮箱登陆的代理实现(swoole)
在工作的过程中,经常会有很多应用有发邮件的需求,这个时候需要在每个应用中配置smtp服务器。一旦公司调整了smtp服务器的配置,比如修改了密码等,这个时候对于维护的人员来说要逐一修改应用中smtp的配置。这样的情况虽然不多见,但遇上了还是很头痛的一件事情。
知道了问题,解决起来就有了方向。于是就有了自己开发一个简单的smtp代理的想法,这个代理主要的功能(参照问题)主要是:
1.接受指定IP应用的smtp请求;
2.应用不需要知道smtp的用户和密码;
3.转发应用的smtp请求。
开发的环境:Linux,php(swoole);
代码如下:
<span style="color: #000000;">php</span><span style="color: #008000;">/*</span><span style="color: #008000;">* * * SMTP Proxy Server * @author Terry Zhang, 2015-11-13 * * @version 1.0 * * 注意:本程序只能运行在cli模式,且需要扩展Swoole 1.7.20+的支持。 * * Swoole的源代码及安装请参考 https://github.com/swoole/swoole-src/ * * 本程序的使用场景: * * 在多个分散的系统中使用同一的邮件地址进行系统邮件发送时,一旦邮箱密码修改,则要修改每个系统的邮件配置参数。 * 同时,在每个系统中配置邮箱参数,使得邮箱的密码容易外泄。 * * 通过本代理进行邮件发送的客户端,可以随便指定用户名和密码。 * * </span><span style="color: #008000;">*/</span><span style="color: #008000;">//</span><span style="color: #008000;">error_reporting(0);</span><span style="color: #008080;">defined</span>('DEBUG_ON') or <span style="color: #008080;">define</span>('DEBUG_ON', <span style="color: #0000ff;">false</span><span style="color: #000000;">);</span><span style="color: #008000;">//</span><span style="color: #008000;">主目录</span><span style="color: #008080;">defined</span>('BASE_PATH') or <span style="color: #008080;">define</span>('BASE_PATH',<span style="color: #000000;"> __DIR__);</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> CSmtpProxy{ </span><span style="color: #008000;">//</span><span style="color: #008000;">软件版本</span> <span style="color: #0000ff;">const</span> VERSION = '1.0'<span style="color: #000000;">; </span><span style="color: #0000ff;">const</span> EOF = "\r\n"<span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$software</span> = "SMTP-Proxy-Server"<span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$server_mode</span> =<span style="color: #000000;"> SWOOLE_PROCESS; </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$pid_file</span><span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$log_file</span><span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$smtp_host</span> = 'localhost'<span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$smtp_port</span> = 25<span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$smtp_user</span> = ''<span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$smtp_pass</span> = ''<span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$smtp_from</span> = ''<span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">待写入文件的日志队列(缓冲区)</span> <span style="color: #0000ff;">private</span> <span style="color: #800080;">$queue</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$host</span> = '0.0.0.0'<span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$port</span> = 25<span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$setting</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #008000;">//</span><span style="color: #008000;">最大连接数</span> <span style="color: #0000ff;">public</span> <span style="color: #800080;">$max_connection</span> = 50<span style="color: #000000;">; </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * @var swoole_server </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">protected</span> <span style="color: #800080;">$server</span><span style="color: #000000;">; </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">$connection</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> setPidFile(<span style="color: #800080;">$pid_file</span><span style="color: #000000;">){ self</span>::<span style="color: #800080;">$pid_file</span> = <span style="color: #800080;">$pid_file</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span> start(<span style="color: #800080;">$startFunc</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span>(!<span style="color: #008080;">extension_loaded</span>('swoole'<span style="color: #000000;">)){ </span><span style="color: #0000ff;">exit</span>("Require extension `swoole`.\n"<span style="color: #000000;">); } </span><span style="color: #800080;">$pid_file</span> = self::<span style="color: #800080;">$pid_file</span><span style="color: #000000;">; </span><span style="color: #800080;">$server_pid</span> = 0<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">is_file</span>(<span style="color: #800080;">$pid_file</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$server_pid</span> = <span style="color: #008080;">file_get_contents</span>(<span style="color: #800080;">$pid_file</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$argv</span>[1<span style="color: #000000;">])){ goto usage; }</span><span style="color: #0000ff;">elseif</span>(<span style="color: #800080;">$argv</span>[1] == 'reload'<span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$server_pid</span><span style="color: #000000;">)){ </span><span style="color: #0000ff;">exit</span>("SMTP Proxy Server is not running\n"<span style="color: #000000;">); } posix_kill(</span><span style="color: #800080;">$server_pid</span>,<span style="color: #000000;"> SIGUSR1); </span><span style="color: #0000ff;">exit</span><span style="color: #000000;">; }</span><span style="color: #0000ff;">elseif</span> (<span style="color: #800080;">$argv</span>[1] == 'stop'<span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$server_pid</span><span style="color: #000000;">)){ </span><span style="color: #0000ff;">exit</span>("SMTP Proxy is not running\n"<span style="color: #000000;">); } posix_kill(</span><span style="color: #800080;">$server_pid</span>,<span style="color: #000000;"> SIGTERM); </span><span style="color: #0000ff;">exit</span><span style="color: #000000;">; }</span><span style="color: #0000ff;">elseif</span> (<span style="color: #800080;">$argv</span>[1] == 'start'<span style="color: #000000;">){ </span><span style="color: #008000;">//</span><span style="color: #008000;">已存在ServerPID,并且进程存在</span> <span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$server_pid</span>) and posix_kill(<span style="color: #800080;">$server_pid</span>,(int) 0<span style="color: #000000;">)){ </span><span style="color: #0000ff;">exit</span>("SMTP Proxy is already running.\n"<span style="color: #000000;">); } </span><span style="color: #008000;">//</span><span style="color: #008000;">启动服务器</span> <span style="color: #800080;">$startFunc</span><span style="color: #000000;">(); }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ usage</span>: <span style="color: #0000ff;">exit</span>("Usage: php {<span style="color: #800080;">$argv</span>[0]} start|stop|reload\n"<span style="color: #000000;">); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$host</span>,<span style="color: #800080;">$port</span><span style="color: #000000;">){ </span><span style="color: #800080;">$flag</span> =<span style="color: #000000;"> SWOOLE_SOCK_TCP; </span><span style="color: #800080;">$this</span>->server = <span style="color: #0000ff;">new</span> swoole_server(<span style="color: #800080;">$host</span>,<span style="color: #800080;">$port</span>,self::<span style="color: #800080;">$server_mode</span>,<span style="color: #800080;">$flag</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>->host = <span style="color: #800080;">$host</span><span style="color: #000000;">; </span><span style="color: #800080;">$this</span>->port = <span style="color: #800080;">$port</span><span style="color: #000000;">; </span><span style="color: #800080;">$this</span>->setting = <span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'backlog' => 128, 'dispatch_mode' => 2,<span style="color: #000000;"> ); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> daemonize(){ </span><span style="color: #800080;">$this</span>->setting['daemonize'] = 1<span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->connection_info(<span style="color: #800080;">$fd</span><span style="color: #000000;">); } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 启动服务进程 * @param array $setting * @throws Exception </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> run(<span style="color: #800080;">$setting</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">()){ </span><span style="color: #800080;">$this</span>->setting = <span style="color: #008080;">array_merge</span>(<span style="color: #800080;">$this</span>->setting,<span style="color: #800080;">$setting</span><span style="color: #000000;">); </span><span style="color: #008000;">//</span><span style="color: #008000;">不使用swoole的默认日志</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">])){ self</span>::<span style="color: #800080;">$log_file</span> = <span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['log_file'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->max_connection = <span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['max_connection'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->smtp_host = <span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_host'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->smtp_port = <span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_port'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->smtp_user = <span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_user'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->smtp_pass = <span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_pass'<span style="color: #000000;">]); } </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">])){ </span><span style="color: #800080;">$this</span>->smtp_from = <span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">]; </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$this</span>->setting['smtp_from'<span style="color: #000000;">]); } </span><span style="color: #800080;">$this</span>->server->set(<span style="color: #800080;">$this</span>-><span style="color: #000000;">setting); </span><span style="color: #800080;">$version</span> = <span style="color: #008080;">explode</span>('.',<span style="color: #000000;"> SWOOLE_VERSION); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$version</span>[0] == 1 && <span style="color: #800080;">$version</span>[1] $version[2] ){ <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">Exception</span>('Swoole version require 1.7.20 +.'<span style="color: #000000;">); } </span><span style="color: #008000;">//</span><span style="color: #008000;">事件绑定</span> <span style="color: #800080;">$this</span>->server->on('start',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onMasterStart'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('shutdown',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onMasterStop'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('ManagerStart',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onManagerStart'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('ManagerStop',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onManagerStop'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('WorkerStart',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerStart'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('WorkerStop',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerStop'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('WorkerError',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onWorkerError'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('Connect',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onConnect'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('Receive',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onReceive'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server->on('Close',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onClose'<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>->server-><span style="color: #000000;">start(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">log</span>(<span style="color: #800080;">$msg</span>,<span style="color: #800080;">$level</span> = 'debug',<span style="color: #800080;">$flush</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(DEBUG_ON){ </span><span style="color: #800080;">$log</span> = <span style="color: #008080;">date</span>('Y-m-d H:i:s').' ['.<span style="color: #800080;">$level</span>."]\t" .<span style="color: #800080;">$msg</span>."\n"<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(self::<span style="color: #800080;">$log_file</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$debug_file</span> = <span style="color: #008080;">dirname</span>(self::<span style="color: #800080;">$log_file</span>).'/debug.log'<span style="color: #000000;">; </span><span style="color: #008080;">file_put_contents</span>(<span style="color: #800080;">$debug_file</span>, <span style="color: #800080;">$log</span>,<span style="color: #000000;">FILE_APPEND); </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">filesize</span>(<span style="color: #800080;">$debug_file</span>) > 10485760){<span style="color: #008000;">//</span><span style="color: #008000;">10M</span> <span style="color: #008080;">unlink</span>(<span style="color: #800080;">$debug_file</span><span style="color: #000000;">); } } </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$log</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$level</span> != 'debug'<span style="color: #000000;">){ </span><span style="color: #008000;">//</span><span style="color: #008000;">日志记录</span> <span style="color: #800080;">$this</span>->queue[] = <span style="color: #008080;">date</span>('Y-m-d H:i:s')."\t[".<span style="color: #800080;">$level</span>."]\t".<span style="color: #800080;">$msg</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">count</span>(<span style="color: #800080;">$this</span>->queue)>10 && !<span style="color: #0000ff;">empty</span>(self::<span style="color: #800080;">$log_file</span>) || <span style="color: #800080;">$flush</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span> (<span style="color: #008080;">filesize</span>(self::<span style="color: #800080;">$log_file</span>) > 209715200){ <span style="color: #008000;">//</span><span style="color: #008000;">200M</span> <span style="color: #008080;">rename</span>(self::<span style="color: #800080;">$log_file</span>,self::<span style="color: #800080;">$log_file</span>.'.'.<span style="color: #008080;">date</span>('His'<span style="color: #000000;">)); } </span><span style="color: #800080;">$logs</span> = ''<span style="color: #000000;">; </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->queue <span style="color: #0000ff;">as</span> <span style="color: #800080;">$q</span><span style="color: #000000;">){ </span><span style="color: #800080;">$logs</span> .= <span style="color: #800080;">$q</span>."\n"<span style="color: #000000;">; } </span><span style="color: #008080;">file_put_contents</span>(self::<span style="color: #800080;">$log_file</span>, <span style="color: #800080;">$logs</span>,<span style="color: #000000;">FILE_APPEND); </span><span style="color: #800080;">$this</span>->queue = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> shutdown(){ </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server-><span style="color: #000000;">shutdown(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> close(<span style="color: #800080;">$fd</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> send(<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$data</span><span style="color: #000000;">){ </span><span style="color: #800080;">$data</span> = <span style="color: #008080;">strtr</span>(<span style="color: #800080;">$data</span>,<span style="color: #0000ff;">array</span>("\n" => "", "\0" => "", "\r" => ""<span style="color: #000000;">)); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t" . <span style="color: #800080;">$data</span><span style="color: #000000;">); </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->server->send(<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$data</span>.self::<span style="color: #000000;">EOF); } </span><span style="color: #008000;">/*</span><span style="color: #008000;">+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 事件回调 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onMasterStart(<span style="color: #800080;">$serv</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">; swoole_set_process_name(</span>'php '.<span style="color: #800080;">$argv</span>[0].': master -host='.<span style="color: #800080;">$this</span>->host.' -port='.<span style="color: #800080;">$this</span>-><span style="color: #000000;">port); </span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->setting['pid_file'<span style="color: #000000;">])){ </span><span style="color: #008080;">file_put_contents</span>(self::<span style="color: #800080;">$pid_file</span>, <span style="color: #800080;">$serv</span>-><span style="color: #000000;">master_pid); } </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Master started.'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onMasterStop(<span style="color: #800080;">$serv</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->setting['pid_file'<span style="color: #000000;">])){ </span><span style="color: #008080;">unlink</span>(self::<span style="color: #800080;">$pid_file</span><span style="color: #000000;">); } </span><span style="color: #800080;">$this</span>->shm-><span style="color: #000000;">delete(); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Master stop.'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onManagerStart(<span style="color: #800080;">$serv</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">; swoole_set_process_name(</span>'php '.<span style="color: #800080;">$argv</span>[0].': manager'<span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Manager started.'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onManagerStop(<span style="color: #800080;">$serv</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Manager stop.'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerStart(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">global</span> <span style="color: #800080;">$argv</span><span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$worker_id</span> >= <span style="color: #800080;">$serv</span>->setting['worker_num'<span style="color: #000000;">]) { swoole_set_process_name(</span>"php {<span style="color: #800080;">$argv</span>[0]}: worker [task]"<span style="color: #000000;">); } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { swoole_set_process_name(</span>"php {<span style="color: #800080;">$argv</span>[0]}: worker [{<span style="color: #800080;">$worker_id</span>}]"<span style="color: #000000;">); } </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} started."<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerStop(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} stop."<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onWorkerError(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$worker_id</span>,<span style="color: #800080;">$worker_pid</span>,<span style="color: #800080;">$exit_code</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("Worker {<span style="color: #800080;">$worker_id</span>} error:{<span style="color: #800080;">$exit_code</span>}."<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onConnect(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">count</span>(<span style="color: #800080;">$this</span>->server->connections) $this-><span style="color: #000000;">max_connection){ </span><span style="color: #800080;">$info</span> = <span style="color: #800080;">$this</span>->getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->isIpAllow(<span style="color: #800080;">$info</span>['remote_ip'<span style="color: #000000;">])){ </span><span style="color: #008000;">//</span><span style="color: #008000;">建立服务器连接</span> <span style="color: #800080;">$cli</span> = <span style="color: #0000ff;">new</span> Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); <span style="color: #008000;">//</span><span style="color: #008000;">异步非阻塞</span> <span style="color: #800080;">$cli</span>->on('connect',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerConnect'<span style="color: #000000;">)); </span><span style="color: #800080;">$cli</span>->on('receive',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerReceive'<span style="color: #000000;">)); </span><span style="color: #800080;">$cli</span>->on('error',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerError'<span style="color: #000000;">)); </span><span style="color: #800080;">$cli</span>->on('close',<span style="color: #0000ff;">array</span>(<span style="color: #800080;">$this</span>,'onServerClose'<span style="color: #000000;">)); </span><span style="color: #800080;">$cli</span>->fd = <span style="color: #800080;">$fd</span><span style="color: #000000;">; </span><span style="color: #800080;">$ip</span> = <span style="color: #008080;">gethostbyname</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_host); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$cli</span>->connect(<span style="color: #800080;">$ip</span>,<span style="color: #800080;">$this</span>->smtp_port) !== <span style="color: #0000ff;">false</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>] = <span style="color: #800080;">$cli</span><span style="color: #000000;">; }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #800080;">$this</span>->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Cannot connect to SMTP server. Connection #'.<span style="color: #800080;">$fd</span>.' close.'<span style="color: #000000;">); } }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Blocked clinet connection, IP deny : '.<span style="color: #800080;">$info</span>['remote_ip'],'warn'<span style="color: #000000;">); </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection #'.<span style="color: #800080;">$fd</span>.' close.'<span style="color: #000000;">); } }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Blocked clinet connection, too many connections.','warn'<span style="color: #000000;">); </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$fd</span><span style="color: #000000;">); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onReceive(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span>,<span style="color: #800080;">$recv_data</span><span style="color: #000000;">){ </span><span style="color: #800080;">$info</span> = <span style="color: #800080;">$this</span>->getConnectionInfo(<span style="color: #800080;">$fd</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P trim(<span style="color: #800080;">$recv_data</span><span style="color: #000000;">)); </span><span style="color: #008000;">//</span><span style="color: #008000;">禁止使用STARTTLS</span> <span style="color: #0000ff;">if</span>(<span style="color: #008080;">strtoupper</span>(<span style="color: #008080;">trim</span>(<span style="color: #800080;">$recv_data</span>)) == 'STARTTLS'<span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->server->send(<span style="color: #800080;">$fd</span>,"502 Not implemented".self::<span style="color: #000000;">EOF); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t502 Not implemented"<span style="color: #000000;">); }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #008000;">//</span><span style="color: #008000;">重置登陆验证 </span> <span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^AUTH\s+LOGIN(.*)/', <span style="color: #800080;">$recv_data</span>,<span style="color: #800080;">$m</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$m</span>[1] = <span style="color: #008080;">trim</span>(<span style="color: #800080;">$m</span>[1<span style="color: #000000;">]); </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$m</span>[1<span style="color: #000000;">])){ </span><span style="color: #008000;">//</span><span style="color: #008000;">只发送AUTH LOGIN 接下来将发送用户名</span> <span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_user; }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #800080;">$recv_data</span> = 'AUTH LOGIN '.<span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->smtp_user).self::<span style="color: #000000;">EOF; </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_pass; } }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^HELO.*|^EHLO.*/', <span style="color: #800080;">$recv_data</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$recv_data</span> = 'HELO '.<span style="color: #800080;">$this</span>->smtp_host.self::<span style="color: #000000;">EOF; } </span><span style="color: #008000;">//</span><span style="color: #008000;">重置密码</span> <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">pass)){ </span><span style="color: #800080;">$recv_data</span> = <span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass).self::<span style="color: #000000;">EOF; </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = ''<span style="color: #000000;">; } </span><span style="color: #008000;">//</span><span style="color: #008000;">重置用户名</span> <span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">user)){ </span><span style="color: #800080;">$recv_data</span> = <span style="color: #008080;">base64_encode</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user).self::<span style="color: #000000;">EOF; </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->user = ''<span style="color: #000000;">; </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->pass = <span style="color: #800080;">$this</span>-><span style="color: #000000;">smtp_pass; } </span><span style="color: #008000;">//</span><span style="color: #008000;">重置mail from</span> <span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/^MAIL\s+FROM:.*/', <span style="color: #800080;">$recv_data</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$recv_data</span> = 'MAIL FROM:$this->smtp_from.'>'.self::<span style="color: #000000;">EOF; } } </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">isConnected()){ </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]->send(<span style="color: #800080;">$recv_data</span><span style="color: #000000;">); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> S]\t".<span style="color: #008080;">trim</span>(<span style="color: #800080;">$recv_data</span><span style="color: #000000;">)); } } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onClose(<span style="color: #800080;">$serv</span>,<span style="color: #800080;">$fd</span>,<span style="color: #800080;">$from_id</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span><span style="color: #000000;">])){ </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">isConnected()){ </span><span style="color: #800080;">$this</span>->connection[<span style="color: #800080;">$fd</span>]-><span style="color: #000000;">close(); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server close.'<span style="color: #000000;">); } } </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection #'.<span style="color: #800080;">$fd</span>.' close. Flush the logs.','debug',<span style="color: #0000ff;">true</span><span style="color: #000000;">); } </span><span style="color: #008000;">/*</span><span style="color: #008000;">--------------------------------------------- * * 服务器连接事件回调 * ----------------------------------------------</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerConnect(<span style="color: #800080;">$cli</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connected to SMTP server.'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerReceive(<span style="color: #800080;">$cli</span>,<span style="color: #800080;">$data</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P trim(<span style="color: #800080;">$data</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->server->send(<span style="color: #800080;">$cli</span>->fd,<span style="color: #800080;">$data</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>("[P --> C]\t".<span style="color: #008080;">trim</span>(<span style="color: #800080;">$data</span><span style="color: #000000;">)); } } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerError(<span style="color: #800080;">$cli</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$cli</span>-><span style="color: #000000;">fd); </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server error: '.<span style="color: #800080;">$cli</span>->errCode.' '.socket_strerror(<span style="color: #800080;">$cli</span>->errCode),'warn'<span style="color: #000000;">); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> onServerClose(<span style="color: #800080;">$cli</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>-><span style="color: #008080;">log</span>('Connection on SMTP server close.'<span style="color: #000000;">); </span><span style="color: #800080;">$this</span>->server->close(<span style="color: #800080;">$cli</span>-><span style="color: #000000;">fd); } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * IP地址过滤 * @param unknown $ip * @return boolean </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> isIpAllow(<span style="color: #800080;">$ip</span><span style="color: #000000;">){ </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['ip']['allow'<span style="color: #000000;">])){ </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->setting['ip']['allow'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$addr</span><span style="color: #000000;">){ </span><span style="color: #800080;">$pattern</span> = '/'.<span style="color: #008080;">str_replace</span>('*','\d+',<span style="color: #008080;">str_replace</span>('.', '\.', <span style="color: #800080;">$addr</span>)).'/'<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>(<span style="color: #800080;">$pattern</span>, <span style="color: #800080;">$ip</span>) && !<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$addr</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">true</span><span style="color: #000000;">; </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; } } } </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$pass</span><span style="color: #000000;">){ </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->setting['ip']['deny'<span style="color: #000000;">])){ </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$this</span>->setting['ip']['deny'] <span style="color: #0000ff;">as</span> <span style="color: #800080;">$addr</span><span style="color: #000000;">){ </span><span style="color: #800080;">$pattern</span> = '/'.<span style="color: #008080;">str_replace</span>('*','\d+',<span style="color: #008080;">str_replace</span>('.', '\.', <span style="color: #800080;">$addr</span>)).'/'<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>(<span style="color: #800080;">$pattern</span>, <span style="color: #800080;">$ip</span>) && !<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$addr</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$pass</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">; </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; } } } } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$pass</span><span style="color: #000000;">; } }</span><span style="color: #0000ff;">class</span> Client <span style="color: #0000ff;">extends</span><span style="color: #000000;"> swoole_client{ </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 记录当前连接 * @var unknown </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #800080;">$fd</span><span style="color: #000000;"> ; </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$user</span> = ''<span style="color: #000000;">; </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * smtp登陆密码 * @var unknown </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #800080;">$pass</span> = ''<span style="color: #000000;">;}</span>
配置文件例子:
<span style="color: #008000;">/*</span><span style="color: #008000;">* * 运行配置</span><span style="color: #008000;">*/</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'worker_num' => 12, 'log_file' => BASE_PATH.'/logs/proxyserver.log', 'pid_file' => BASE_PATH.'/logs/proxyserver.pid', 'heartbeat_idle_time' => 300, 'heartbeat_check_interval' => 60, 'max_connection' => 50, <br> //配置真实的smtp信息 'smtp_host' => '', 'smtp_port' => 25, 'smtp_user' => '', 'smtp_pass' => '', 'smtp_from' => '', 'ip' => <span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'allow' => <span style="color: #0000ff;">array</span>('192.168.0.*'), 'deny' => <span style="color: #0000ff;">array</span>('192.168.10.*','192.168.100.*'),<span style="color: #000000;"> ));</span>
运行例子:
defined('BASE_PATH') or define('BASE_PATH', __DIR__);defined('DEBUG_ON') or define('DEBUG_ON', true);//服务器配置require BASE_PATH.'/CSmtpProxy.php';$settings = require BASE_PATH.'/conf/config.php';CSmtpProxy::setPidFile($settings['pid_file']);CSmtpProxy::start(function(){ global $settings; $serv = new CSmtpProxy('0.0.0.0', 25); $serv->daemonize(); $serv->run($settings);});
应用配置:
smtp host: 192.168.0.* //指定smtpproxy 运行的服务器IP。
port: 25
user: xxxx //随意填写
pass: xxxx //随意填写
from: [email protected] // 根据情况填写
——————————————————————————————————————————————————————
存在的问题:
1、不支持ssl模式;
2、应用的from还是要填写正确,否则发出的邮件发件人会显示错误。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

많은 사용자들이 스마트 시계를 선택할 때 Huawei 브랜드를 선택하게 됩니다. 그 중 Huawei GT3pro와 GT4가 가장 인기 있는 선택입니다. 두 제품의 차이점을 궁금해하는 사용자가 많습니다. Huawei GT3pro와 GT4의 차이점은 무엇입니까? 1. 외관 GT4: 46mm와 41mm, 재질은 유리 거울 + 스테인레스 스틸 본체 + 고해상도 섬유 후면 쉘입니다. GT3pro: 46.6mm 및 42.9mm, 재질은 사파이어 유리 + 티타늄 본체/세라믹 본체 + 세라믹 백 쉘입니다. 2. 건강한 GT4: 최신 Huawei Truseen5.5+ 알고리즘을 사용하면 결과가 더 정확해집니다. GT3pro: ECG 심전도, 혈관 및 안전성 추가

WindowsServerBackup은 WindowsServer 운영 체제와 함께 제공되는 기능으로, 사용자가 중요한 데이터 및 시스템 구성을 보호하고 중소기업 및 대기업 수준의 기업에 완벽한 백업 및 복구 솔루션을 제공하도록 설계되었습니다. Server2022 이상을 실행하는 사용자만 이 기능을 사용할 수 있습니다. 이 문서에서는 WindowsServerBackup을 설치, 제거 또는 재설정하는 방법을 설명합니다. Windows Server 백업을 재설정하는 방법 서버 백업에 문제가 있거나 백업에 너무 오랜 시간이 걸리거나 저장된 파일에 액세스할 수 없는 경우 Windows Server 백업 설정을 재설정하는 것을 고려할 수 있습니다. Windows를 재설정하려면

Windows 11에서 캡처 도구가 작동하지 않는 이유 문제의 근본 원인을 이해하면 올바른 솔루션을 찾는 데 도움이 될 수 있습니다. 캡처 도구가 제대로 작동하지 않는 주요 이유는 다음과 같습니다. 초점 도우미가 켜져 있습니다. 이렇게 하면 캡처 도구가 열리지 않습니다. 손상된 응용 프로그램: 캡처 도구가 실행 시 충돌하는 경우 응용 프로그램이 손상되었을 수 있습니다. 오래된 그래픽 드라이버: 호환되지 않는 드라이버가 캡처 도구를 방해할 수 있습니다. 다른 응용 프로그램의 간섭: 실행 중인 다른 응용 프로그램이 캡처 도구와 충돌할 수 있습니다. 인증서가 만료되었습니다. 업그레이드 프로세스 중 오류로 인해 이 문제가 발생할 수 있습니다. 이 문제는 대부분의 사용자에게 적합하며 특별한 기술 지식이 필요하지 않습니다. 1. Windows 및 Microsoft Store 앱 업데이트

PHP는 웹 개발 분야에서 널리 사용되는 강력한 프로그래밍 언어입니다. SMTP 이메일 기능도 PHP 개발의 중요한 부분입니다. 그러나 경우에 따라 SMTP 메일 기능을 비활성화할 수 있으며 이 문서에서는 이를 수행하는 방법을 설명합니다.

nginx의 기본 이름을 수정하는 방법은 조금 위장하거나 설치할 수 있습니다. 팁: 일반적으로 수정은 nginx가 컴파일되기 전에 이루어집니다. 수정 후에는 scr/core/nginx.conf#definenginx_version"1.4.7"#definenginx_ver"nginx/"n과 같이 코드를 다시 컴파일해야 합니다.

Microsoft는 Windows Server 빌드 26040 버전을 출시하면서 제품의 공식 이름을 Windows Server 2025로 발표했습니다. Windows11WindowsInsiderCanaryChannel 버전 build26040도 출시되었습니다. 일부 친구들은 수년 전에 누군가 Windows NT를 워크스테이션 모드에서 서버 모드로 성공적으로 전환하여 다양한 버전의 Microsoft 운영 체제 간의 공통점을 보여주었다는 것을 아직도 기억할 것입니다. 마이크로소프트의 현재 서버 운영체제 버전과 윈도우 11 사이에는 뚜렷한 차이가 있지만, 세부 사항에 주목하는 사람들은 윈도우 서버가 왜 브랜드를 업데이트했는지,

1부: 초기 문제 해결 단계 Apple 시스템 상태 확인: 복잡한 솔루션을 살펴보기 전에 기본 사항부터 시작해 보겠습니다. 문제는 귀하의 기기에 있는 것이 아닐 수도 있습니다. Apple 서버가 다운되었을 수도 있습니다. Apple의 시스템 상태 페이지를 방문하여 AppStore가 제대로 작동하는지 확인하세요. 문제가 있는 경우 Apple이 문제를 해결하기를 기다리는 것뿐입니다. 인터넷 연결 확인: "AppStore에 연결할 수 없음" 문제는 때때로 연결 불량으로 인해 발생할 수 있으므로 인터넷 연결이 안정적인지 확인하십시오. Wi-Fi와 모바일 데이터 간을 전환하거나 네트워크 설정을 재설정해 보세요(일반 > 재설정 > 네트워크 설정 재설정 > 설정). iOS 버전을 업데이트하세요.

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code
