tag:blogger.com,1999:blog-4088605343010946072023-11-16T14:41:17.753+08:00Queueing Theory To YCWang®To record my study for the queueing theory, and wish these articles can help you while you are learning this subject. Besides, I write this blog to deeply appreciate my teacher(Prof. Wang,Yung-Chung).Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.comBlogger61125tag:blogger.com,1999:blog-408860534301094607.post-84685848165620593062011-01-14T15:19:00.003+08:002011-04-05T15:14:17.077+08:00CongratulationsThis is my congratulations to my teacher, YCWang.<br />
<br />
YCWang has been promoted to the professor!<br />
<ul><li>教授=professor</li>
<li>副教授=associate professor</li>
<li>助理教授=assistant professor</li>
</ul><div>###</div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-21118193993401847432010-08-13T11:49:00.002+08:002010-08-13T12:02:11.018+08:00httpd.conf 組態檔紀錄Apache HTTP Server的組態檔(configuration file),這是預設的原始檔案內容,版本是Apache 2.2.16版。注意下方粗體字是常用的組態指令與注意事項。<br />
<br />
#<br />
# This is the main Apache HTTP server configuration file. It contains the<br />
# configuration directives that give the server its instructions.<br />
# See <url:http://httpd.apache.org/docs/2.2> for detailed information.</url:http://httpd.apache.org/docs/2.2><br />
# In particular, see<br />
# <url:http://httpd.apache.org/docs/2.2/mod/directives.html></url:http://httpd.apache.org/docs/2.2/mod/directives.html><br />
# for a discussion of each configuration directive.<br />
#<br />
# <b>Do NOT simply read the instructions in here without understanding</b><br />
# <b>what they do.</b> They're here only as hints or reminders. If you are unsure<br />
# consult the online docs. You have been warned. <br />
#<br />
# Configuration and logfile names: If the filenames you specify for many<br />
# of the server's control files begin with "/" (or "drive:/" for Win32), the<br />
# server will use that explicit path. If the filenames do *not* begin<br />
# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"<br />
# with ServerRoot set to "C:/Program Files/Apache Software Foundation/Apache2.2" will be interpreted by the<br />
# server as "C:/Program Files/Apache Software Foundation/Apache2.2/logs/foo.log".<br />
#<br />
# <b>NOTE: Where filenames are specified, you must use forward slashes</b><br />
# <b>instead of backslashes (e.g., "c:/apache" instead of "c:\apache").</b><br />
# If a drive letter is omitted, the drive on which httpd.exe is located<br />
# will be used by default. It is recommended that you always supply<br />
# an explicit drive letter in absolute paths to avoid confusion.<br />
<br />
#<br />
# ServerRoot: The top of the directory tree under which the server's<br />
# configuration, error, and log files are kept.<br />
#<br />
# <b>Do not add a slash at the end of the directory path.</b> If you point<br />
# ServerRoot at a non-local disk, be sure to point the LockFile directive<br />
# at a local disk. If you wish to share the same ServerRoot for multiple<br />
# httpd daemons, you will need to change at least LockFile and PidFile.<br />
#<br />
<b>ServerRoot "C:/Program Files/Apache Software Foundation/Apache2.2"</b><br />
<br />
#<br />
# Listen: Allows you to bind Apache to specific IP addresses and/or<br />
# ports, instead of the default. See also the <virtualhost></virtualhost><br />
# directive.<br />
#<br />
# Change this to Listen on specific IP addresses as shown below to<br />
# prevent Apache from glomming onto all bound IP addresses.<br />
#<br />
#Listen 12.34.56.78:80<br />
<b>Listen 80</b><br />
<br />
#<br />
# Dynamic Shared Object (DSO) Support<br />
#<br />
# To be able to use the functionality of a module which was built as a DSO you<br />
# have to place corresponding `LoadModule' lines at this location so the<br />
# directives contained in it are actually available _before_ they are used.<br />
# Statically compiled modules (those listed by `httpd -l') do not need<br />
# to be loaded here.<br />
#<br />
# Example:<br />
# LoadModule foo_module modules/mod_foo.so<br />
#<br />
LoadModule actions_module modules/mod_actions.so<br />
LoadModule alias_module modules/mod_alias.so<br />
LoadModule asis_module modules/mod_asis.so<br />
LoadModule auth_basic_module modules/mod_auth_basic.so<br />
#LoadModule auth_digest_module modules/mod_auth_digest.so<br />
#LoadModule authn_alias_module modules/mod_authn_alias.so<br />
#LoadModule authn_anon_module modules/mod_authn_anon.so<br />
#LoadModule authn_dbd_module modules/mod_authn_dbd.so<br />
#LoadModule authn_dbm_module modules/mod_authn_dbm.so<br />
LoadModule authn_default_module modules/mod_authn_default.so<br />
LoadModule authn_file_module modules/mod_authn_file.so<br />
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so<br />
#LoadModule authz_dbm_module modules/mod_authz_dbm.so<br />
LoadModule authz_default_module modules/mod_authz_default.so<br />
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so<br />
LoadModule authz_host_module modules/mod_authz_host.so<br />
#LoadModule authz_owner_module modules/mod_authz_owner.so<br />
LoadModule authz_user_module modules/mod_authz_user.so<br />
LoadModule autoindex_module modules/mod_autoindex.so<br />
#LoadModule cache_module modules/mod_cache.so<br />
#LoadModule cern_meta_module modules/mod_cern_meta.so<br />
LoadModule cgi_module modules/mod_cgi.so<br />
#LoadModule charset_lite_module modules/mod_charset_lite.so<br />
#LoadModule dav_module modules/mod_dav.so<br />
#LoadModule dav_fs_module modules/mod_dav_fs.so<br />
#LoadModule dav_lock_module modules/mod_dav_lock.so<br />
#LoadModule dbd_module modules/mod_dbd.so<br />
#LoadModule deflate_module modules/mod_deflate.so<br />
LoadModule dir_module modules/mod_dir.so<br />
#LoadModule disk_cache_module modules/mod_disk_cache.so<br />
#LoadModule dumpio_module modules/mod_dumpio.so<br />
LoadModule env_module modules/mod_env.so<br />
#LoadModule expires_module modules/mod_expires.so<br />
#LoadModule ext_filter_module modules/mod_ext_filter.so<br />
#LoadModule file_cache_module modules/mod_file_cache.so<br />
#LoadModule filter_module modules/mod_filter.so<br />
#LoadModule headers_module modules/mod_headers.so<br />
#LoadModule ident_module modules/mod_ident.so<br />
#LoadModule imagemap_module modules/mod_imagemap.so<br />
LoadModule include_module modules/mod_include.so<br />
#LoadModule info_module modules/mod_info.so<br />
LoadModule isapi_module modules/mod_isapi.so<br />
#LoadModule ldap_module modules/mod_ldap.so<br />
#LoadModule logio_module modules/mod_logio.so<br />
LoadModule log_config_module modules/mod_log_config.so<br />
#LoadModule log_forensic_module modules/mod_log_forensic.so<br />
#LoadModule mem_cache_module modules/mod_mem_cache.so<br />
LoadModule mime_module modules/mod_mime.so<br />
#LoadModule mime_magic_module modules/mod_mime_magic.so<br />
LoadModule negotiation_module modules/mod_negotiation.so<br />
#LoadModule proxy_module modules/mod_proxy.so<br />
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so<br />
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so<br />
#LoadModule proxy_connect_module modules/mod_proxy_connect.so<br />
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so<br />
#LoadModule proxy_http_module modules/mod_proxy_http.so<br />
#LoadModule reqtimeout_module modules/mod_reqtimeout.so<br />
#LoadModule rewrite_module modules/mod_rewrite.so<br />
LoadModule setenvif_module modules/mod_setenvif.so<br />
#LoadModule speling_module modules/mod_speling.so<br />
#LoadModule ssl_module modules/mod_ssl.so<br />
#LoadModule status_module modules/mod_status.so<br />
#LoadModule substitute_module modules/mod_substitute.so<br />
#LoadModule unique_id_module modules/mod_unique_id.so<br />
#LoadModule userdir_module modules/mod_userdir.so<br />
#LoadModule usertrack_module modules/mod_usertrack.so<br />
#LoadModule version_module modules/mod_version.so<br />
#LoadModule vhost_alias_module modules/mod_vhost_alias.so<br />
<br />
<ifmodule !mpm_netware_module=""></ifmodule><br />
<ifmodule !mpm_winnt_module=""></ifmodule><br />
#<br />
# If you wish httpd to run as a different user or group, you must run<br />
# httpd as root initially and it will switch. <br />
#<br />
# User/Group: The name (or #number) of the user/group to run httpd as.<br />
# It is usually good practice to create a dedicated user and group for<br />
# running httpd, as with most system services.<br />
#<br />
User daemon<br />
Group daemon<br />
<br />
<br />
<br />
<br />
# 'Main' server configuration<br />
#<br />
# The directives in this section set up the values used by the 'main'<br />
# server, which responds to any requests that aren't handled by a<br />
# <virtualhost> definition. These values also provide defaults for</virtualhost><br />
# any <virtualhost> containers you may define later in the file.</virtualhost><br />
#<br />
# All of these directives may appear inside <virtualhost> containers,</virtualhost><br />
# in which case these default settings will be overridden for the<br />
# virtual host being defined.<br />
#<br />
<br />
#<br />
# ServerAdmin: Your address, where problems with the server should be<br />
# e-mailed. This address appears on some server-generated pages, such<br />
# as error documents. e.g. admin@your-domain.com<br />
#<br />
ServerAdmin admin@localhost<br />
<br />
#<br />
# ServerName gives the name and port that the server uses to identify itself.<br />
# This can often be determined automatically, but we recommend you specify<br />
# it explicitly to prevent problems during startup.<br />
#<br />
# If your host doesn't have a registered DNS name, enter its IP address here.<br />
#<br />
#ServerName localhost:80<br />
<br />
#<br />
# DocumentRoot: The directory out of which you will serve your<br />
# documents. By default, all requests are taken from this directory, but<br />
# symbolic links and aliases may be used to point to other locations.<br />
#<br />
<b>DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"</b><br />
<br />
#<br />
# Each directory to which Apache has access can be configured with respect<br />
# to which services and features are allowed and/or disabled in that<br />
# directory (and its subdirectories).<br />
#<br />
# First, we configure the "default" to be a very restrictive set of<br />
# features. <br />
#<br />
<directory></directory><br />
Options FollowSymLinks<br />
AllowOverride None<br />
Order deny,allow<br />
Deny from all<br />
<br />
<br />
#<br />
# Note that from this point forward you must specifically allow<br />
# particular features to be enabled - so if something's not working as<br />
# you might expect, make sure that you have specifically enabled it<br />
# below.<br />
#<br />
<br />
#<br />
# This should be changed to whatever you set DocumentRoot to.<br />
#<br />
<directory apache2.2="" apache="" c:="" files="" foundation="" htdocs"="" program="" software=""></directory><br />
#<br />
# Possible values for the Options directive are "None", "All",<br />
# or any combination of:<br />
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews<br />
#<br />
# Note that "MultiViews" must be named *explicitly* --- "Options All"<br />
# doesn't give it to you.<br />
#<br />
# The Options directive is both complicated and important. Please see<br />
# http://httpd.apache.org/docs/2.2/mod/core.html#options<br />
# for more information.<br />
#<br />
Options Indexes FollowSymLinks<br />
<br />
#<br />
# AllowOverride controls what directives may be placed in .htaccess files.<br />
# It can be "All", "None", or any combination of the keywords:<br />
# Options FileInfo AuthConfig Limit<br />
#<br />
AllowOverride None<br />
<br />
#<br />
# Controls who can get stuff from this server.<br />
#<br />
Order allow,deny<br />
Allow from all<br />
<br />
<br />
<br />
#<br />
# DirectoryIndex: sets the file that Apache will serve if a directory<br />
# is requested.<br />
#<br />
<ifmodule dir_module=""></ifmodule><br />
<b> DirectoryIndex index.html</b><br />
<br />
<br />
#<br />
# The following lines prevent .htaccess and .htpasswd files from being<br />
# viewed by Web clients.<br />
#<br />
<filesmatch ^\.ht"=""></filesmatch><br />
Order allow,deny<br />
Deny from all<br />
Satisfy All<br />
<br />
<br />
#<br />
# ErrorLog: The location of the error log file.<br />
# If you do not specify an ErrorLog directive within a <virtualhost></virtualhost><br />
# container, error messages relating to that virtual host will be<br />
# logged here. If you *do* define an error logfile for a <virtualhost></virtualhost><br />
# container, that host's errors will be logged there and not here.<br />
#<br />
ErrorLog "logs/error.log"<br />
<br />
#<br />
# LogLevel: Control the number of messages logged to the error_log.<br />
# Possible values include: debug, info, notice, warn, error, crit,<br />
# alert, emerg.<br />
#<br />
LogLevel warn<br />
<br />
<ifmodule log_config_module=""></ifmodule><br />
#<br />
# The following directives define some format nicknames for use with<br />
# a CustomLog directive (see below).<br />
#<br />
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined<br />
LogFormat "%h %l %u %t \"%r\" %>s %b" common<br />
<br />
<ifmodule logio_module=""></ifmodule><br />
# You need to enable mod_logio.c to use %I and %O<br />
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio<br />
<br />
<br />
#<br />
# The location and format of the access logfile (Common Logfile Format).<br />
# If you do not define any access logfiles within a <virtualhost></virtualhost><br />
# container, they will be logged here. Contrariwise, if you *do*<br />
# define per-<virtualhost> access logfiles, transactions will be</virtualhost><br />
# logged therein and *not* in this file.<br />
#<br />
CustomLog "logs/access.log" common<br />
<br />
#<br />
# If you prefer a logfile with access, agent, and referer information<br />
# (Combined Logfile Format) you can use the following directive.<br />
#<br />
#CustomLog "logs/access.log" combined<br />
<br />
<br />
<ifmodule alias_module=""></ifmodule><br />
#<br />
# Redirect: Allows you to tell clients about documents that used to<br />
# exist in your server's namespace, but do not anymore. The client<br />
# will make a new request for the document at its new location.<br />
# Example:<br />
# Redirect permanent /foo http://localhost/bar<br />
<br />
#<br />
# Alias: Maps web paths into filesystem paths and is used to<br />
# access content that does not live under the DocumentRoot.<br />
# Example:<br />
# Alias /webpath /full/filesystem/path<br />
#<br />
# If you include a trailing / on /webpath then the server will<br />
# require it to be present in the URL. You will also likely<br />
# need to provide a <directory> section to allow access to</directory><br />
# the filesystem path.<br />
<br />
#<br />
# ScriptAlias: This controls which directories contain server scripts.<br />
# ScriptAliases are essentially the same as Aliases, except that<br />
# documents in the target directory are treated as applications and<br />
# run by the server when requested rather than as documents sent to the<br />
# client. The same rules about trailing "/" apply to ScriptAlias<br />
# directives as to Alias.<br />
#<br />
ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"<br />
<br />
<br />
<br />
<ifmodule cgid_module=""></ifmodule><br />
#<br />
# ScriptSock: On threaded servers, designate the path to the UNIX<br />
# socket used to communicate with the CGI daemon of mod_cgid.<br />
#<br />
#Scriptsock logs/cgisock<br />
<br />
<br />
#<br />
# "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin" should be changed to whatever your ScriptAliased<br />
# CGI directory exists, if you have that configured.<br />
#<br />
<directory apache2.2="" apache="" c:="" cgi-bin"="" files="" foundation="" program="" software=""></directory><br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all<br />
<br />
<br />
#<br />
# DefaultType: the default MIME type the server will use for a document<br />
# if it cannot otherwise determine one, such as from filename extensions.<br />
# If your server contains mostly text or HTML documents, "text/plain" is<br />
# a good value. If most of your content is binary, such as applications<br />
# or images, you may want to use "application/octet-stream" instead to<br />
# keep browsers from trying to display binary files as though they are<br />
# text.<br />
#<br />
DefaultType text/plain<br />
<br />
<ifmodule mime_module=""></ifmodule><br />
#<br />
# TypesConfig points to the file containing the list of mappings from<br />
# filename extension to MIME-type.<br />
#<br />
TypesConfig conf/mime.types<br />
<br />
#<br />
# AddType allows you to add to or override the MIME configuration<br />
# file specified in TypesConfig for specific file types.<br />
#<br />
#AddType application/x-gzip .tgz<br />
#<br />
# AddEncoding allows you to have certain browsers uncompress<br />
# information on the fly. Note: Not all browsers support this.<br />
#<br />
#AddEncoding x-compress .Z<br />
#AddEncoding x-gzip .gz .tgz<br />
#<br />
# If the AddEncoding directives above are commented-out, then you<br />
# probably should define those extensions to indicate media types:<br />
#<br />
AddType application/x-compress .Z<br />
AddType application/x-gzip .gz .tgz<br />
<br />
#<br />
# AddHandler allows you to map certain file extensions to "handlers":<br />
# actions unrelated to filetype. These can be either built into the server<br />
# or added with the Action directive (see below)<br />
#<br />
# To use CGI scripts outside of ScriptAliased directories:<br />
# (You will also need to add "ExecCGI" to the "Options" directive.)<br />
#<br />
#AddHandler cgi-script .cgi<br />
<br />
# For type maps (negotiated resources):<br />
#AddHandler type-map var<br />
<br />
#<br />
# Filters allow you to process content before it is sent to the client.<br />
#<br />
# To parse .shtml files for server-side includes (SSI):<br />
# (You will also need to add "Includes" to the "Options" directive.)<br />
#<br />
#AddType text/html .shtml<br />
#AddOutputFilter INCLUDES .shtml<br />
<br />
<br />
#<br />
# The mod_mime_magic module allows the server to use various hints from the<br />
# contents of the file itself to determine its type. The MIMEMagicFile<br />
# directive tells the module where the hint definitions are located.<br />
#<br />
#MIMEMagicFile conf/magic<br />
<br />
#<br />
# Customizable error responses come in three flavors:<br />
# 1) plain text 2) local redirects 3) external redirects<br />
#<br />
# Some examples:<br />
#ErrorDocument 500 "The server made a boo boo."<br />
#ErrorDocument 404 /missing.html<br />
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"<br />
#ErrorDocument 402 http://localhost/subscription_info.html<br />
#<br />
<br />
#<br />
# EnableMMAP and EnableSendfile: On systems that support it,<br />
# memory-mapping or the sendfile syscall is used to deliver<br />
# files. This usually improves server performance, but must<br />
# be turned off when serving from networked-mounted<br />
# filesystems or if support for these functions is otherwise<br />
# broken on your system.<br />
#<br />
#EnableMMAP off<br />
#EnableSendfile off<br />
<br />
# Supplemental configuration<br />
#<br />
# The configuration files in the conf/extra/ directory can be<br />
# included to add extra features or to modify the default configuration of<br />
# the server, or you may simply copy their contents here and change as<br />
# necessary.<br />
<br />
# Server-pool management (MPM specific)<br />
#Include conf/extra/httpd-mpm.conf<br />
<br />
# Multi-language error messages<br />
#Include conf/extra/httpd-multilang-errordoc.conf<br />
<br />
# Fancy directory listings<br />
#Include conf/extra/httpd-autoindex.conf<br />
<br />
# Language settings<br />
#Include conf/extra/httpd-languages.conf<br />
<br />
# User home directories<br />
#Include conf/extra/httpd-userdir.conf<br />
<br />
# Real-time info on requests and configuration<br />
#Include conf/extra/httpd-info.conf<br />
<br />
# Virtual hosts<br />
#Include conf/extra/httpd-vhosts.conf<br />
<br />
# Local access to the Apache HTTP Server Manual<br />
#Include conf/extra/httpd-manual.conf<br />
<br />
# Distributed authoring and versioning (WebDAV)<br />
#Include conf/extra/httpd-dav.conf<br />
<br />
# Various default settings<br />
#Include conf/extra/httpd-default.conf<br />
<br />
# Secure (SSL/TLS) connections<br />
#Include conf/extra/httpd-ssl.conf<br />
#<br />
# Note: The following must must be present to support<br />
# starting without SSL on platforms with no /dev/random equivalent<br />
# but a statically compiled-in mod_ssl.<br />
#<br />
<ifmodule ssl_module=""></ifmodule><br />
SSLRandomSeed startup builtin<br />
SSLRandomSeed connect builtin<br />
<br />
<div><br />
</div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-10689100270977934302010-08-13T00:09:00.001+08:002010-08-13T12:03:19.946+08:00Apache HTTP Server 主目錄今天看看Apache HTTP Server安裝於Win32目錄之下的情形,一般來說,預設值的安裝路徑是<b>C:\Program Files\Apache Software Foundation\Apache2.2</b>之中,裡面的資料夾與檔案如下:<br />
<ul><li>檔案資料夾</li>
<ul><li>bin,<br />
主程式(<b>httpd.exe</b>)的存放位置,還有一些工具像是ApacheMonitor.exe的程式。</li>
<li>cgi-bin,<br />
儲存CGI script的地方。</li>
<li>conf,<br />
組態檔(Configuration File)的存放位置,最重要的是<b>httpd.conf</b>檔案</li>
<li>error,<br />
錯誤訊息頁面。</li>
<li>htdocs,<br />
網站根目錄的位置。</li>
<li>icons,<br />
存放圖示檔。</li>
<li>logs,<br />
存放日誌檔案,像是access.log和error.log。</li>
<li>manual,<br />
使用手冊。</li>
<li>modules,<br />
模組的存放位置。</li>
</ul>
<li>檔案</li>
<ul><li>ABOUT_APACHE.txt,說明Apache HTTP Server是什麼、做什麼、誰做的。</li>
<li>CHANGES.txt,修改記錄</li>
<li>INSTALL.txt,安裝說明文件</li>
<li>LICENSE.txt,授權條款(許可說明文件)</li>
<li>NOTICE.txt,注意事項</li>
<li>README.txt,請先讀我檔案</li>
<li>README-win32.txt,有關Windows平台的README檔案</li>
</ul></ul><div>###</div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-80899113058216551052010-08-12T00:05:00.001+08:002010-08-12T23:38:36.501+08:00Apache The Definitive Guide 技術手冊經過了一年多一點,這段期間累積對於Windows應用程式開發的知識與經驗,現在回頭看看Apache,我的視野已經不再是相同的高度。再次重拾書籍複習,這本書是「<b>Apache技術手冊(第三版)</b>」,大概是中文書裡唯一有關Apache的經典翻譯書籍!前一年,沒有時間細細品味Apache的美,現在經歷多了,有能力可以仔細咀嚼那其中的奧妙之處。<br />
<br />
這只是開端。This is an inception.<br />
<br />
<table style="width: auto;"><tbody>
<tr><td><a href="http://picasaweb.google.com/lh/photo/rlZkp--cVURbSdzdc91OKA?feat=embedwebsite"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtWb-kFe91qH-P6QkmN8W7tj-ni6bn9ox1tKDLIqovFwJK_eEBtPsCn4NbDaW_GS3Z_y4Poefg2HPI7qvbYe9FYgyrgQceIvuX1c1mb_IS9wE4v_vWRaAKJfvfPHHhq1T5Rth8p_VLPSA/s400/Picture%2053.jpg" /></a></td></tr>
</tbody></table>Ben Laurie & Peter Laurie原著,郭文生編譯,<a href="http://www.oreilly.com.tw/product_web.php?id=a128">Apache技術手冊(第三版)</a>,台北:歐萊禮,2003。<br />
<br />
發行者:<a href="http://www.oreilly.com.tw/">美商歐萊禮股份有限公司台灣分公司(O'Reilly Media, Inc. Taiwan Branch)</a><br />
<br />
目錄<br />
<br />
第一章 Apache 入門<br />
<ul><li>Web伺服器的功能</li>
<li>Apache的運作方式</li>
<li>Apache與網路</li>
<li>HTTP客戶端的運作方式</li>
<li>伺服端的運作方式</li>
<li>Apache之安裝規劃</li>
<li>Windows的問題</li>
<li>Apache的版本</li>
<li>安裝Apache</li>
<li>Unix下建製Apache 1.3.X</li>
<li>Apache 2.0的新功能</li>
<li>在Unix下製成與安裝Apache 2.0</li>
<li>Windows下的Apache</li>
</ul>第二章 設定 Apache:起手式<br />
<ul><li>Apache 網站的背後</li>
<li>site.toddle</li>
<li>架設 Unix 伺服器</li>
<li>指令</li>
</ul>第三章 建立真實網站<br />
<ul><li>較佳的網站:site.simple</li>
<li>Butterthlies 公司上線了</li>
<li>區塊指令</li>
<li>其它的指令</li>
<li>HTTP 的回應標頭</li>
<li>再啟動</li>
<li>.htaccess</li>
<li>CERN 中介檔</li>
<li>逾期</li>
</ul>第四章 虛擬主機<br />
<ul><li>兩個網站與 Apache</li>
<li>虛擬主機</li>
<li>兩個 Apache 的分身</li>
<li>動態設定的虛擬主機</li>
</ul>第五章 驗證<br />
<ul><li>驗證協定</li>
<li>驗證指令</li>
<li>Unix 下的密碼</li>
<li>Win32 下的密碼</li>
<li>Web 上的密碼</li>
<li>從用戶端的觀點出發</li>
<li>CGI Script</li>
<li>主題的變化</li>
<li>Order、Allow、與 Deny</li>
<li>Unix 上的 DBM 檔</li>
<li>摘要驗證</li>
<li>匿名存取</li>
<li>實驗</li>
<li>自動的使用者資訊</li>
<li>使用 .htaccess 檔</li>
<li>指令的改寫</li>
</ul>第六章 網頁內容描述與修正<br />
<ul><li>MIME 類型</li>
<li>網頁內容協商</li>
<li>語言協商</li>
<li>類型對應表</li>
<li>瀏覽器與 HTTP 1.1</li>
<li>過濾器</li>
</ul>第七章 製作索引<br />
<ul><li>製作較佳的索引</li>
<li>製作自己的索引</li>
<li>影像地圖(Imagemap)</li>
<li>影像地圖的指令</li>
</ul>第八章 重導向<br />
<ul><li>Alias</li>
<li>Rewrite</li>
<li>重寫的範例</li>
<li>拼字</li>
</ul>第九章 代理伺服器<br />
<ul><li>安全防護</li>
<li>代理伺服器的指令</li>
<li>外表上的錯誤</li>
<li>效能</li>
<li>設定</li>
</ul>第十章 日誌紀錄<br />
<ul><li>用 Script 及資料庫建立日誌</li>
<li>Apache 的日誌機制</li>
<li>組態的日誌紀錄</li>
<li>AddModuleInfo</li>
<li>狀態</li>
</ul>第十一章 安全防護<br />
<ul><li>內部與外部使用者</li>
<li>數位簽章、虛擬現金</li>
<li>憑證</li>
<li>防火牆</li>
<li>法律上的問題</li>
<li>Secure Sockets Layer(SSL)</li>
<li>Apache 的安全防護措施</li>
<li>SSL 的指令</li>
<li>密碼套件</li>
<li>實際狀況下的安全防護</li>
<li>未來的方向</li>
</ul>第十二章 執行大型網站<br />
<ul><li>主機架設</li>
<li>伺服器的安全防護</li>
<li>管理大型網站</li>
<li>支援軟體</li>
<li>擴充性</li>
<li>負載平衡</li>
</ul>第十三章 建製應用程式<br />
<ul><li>以網站當作應用程式</li>
<li>提供應用程式的邏輯</li>
<li>XML、XSLT,與 Web 應用程式</li>
</ul>第十四章 伺服端擴充<br />
<ul><li>檔案大小</li>
<li>檔案修改時間</li>
<li>引入</li>
<li>執行 CGI</li>
<li>Echo</li>
<li>Apache v2:SSI 過濾器</li>
</ul>第十五章 PHP<br />
<ul><li>安裝 PHP</li>
<li>site.php</li>
</ul>第十六章 CGI 與 Perl<br />
<ul><li>CGI 的世界</li>
<li>告訴 Apache 關於 script 的資訊『318』</li>
<li>設定環境變數</li>
<li>Cookies</li>
<li>Script 指令</li>
<li>Unix 上的 suEXEC</li>
<li>處理器(Handler)</li>
<li>Actions</li>
<li>瀏覽器</li>
</ul>第十七章 mod_perl<br />
<ul><li>mod_perl 的運作方式</li>
<li>mod_perl 的文件</li>
<li>安裝 mod_perl — 簡易法</li>
<li>修正你的 script 以便在 mod_perl 下執行</li>
<li>全域變數</li>
<li>Strict 前置條件</li>
<li>載入變動</li>
<li>開啟與關閉檔案</li>
<li>設定 Apache 以使用 mod_perl</li>
</ul>第十八章 mod_jserv 與 Tomcat<br />
<ul><li>mod_jserv</li>
<li>Tomcat</li>
<li>連接 Tomcat 與 Apache</li>
</ul>第十九章 XML 與 Cocoon<br />
<ul><li>XML</li>
<li>XML 與 Perl</li>
<li>Cocoon</li>
<li>Cocoon 1.8 與 JServ</li>
<li>Cocoon 2.0.3 與 Tomcat</li>
<li>測試 Cocoon</li>
</ul>第二十章 Apache 的 API<br />
<ul><li>文件</li>
<li>APR</li>
<li>集散區(Pool)</li>
<li>以伺服器為基準的組態</li>
<li>以目錄為基準的組態</li>
<li>以請求為基準(per-request)的資訊</li>
<li>存取組態與請求資訊</li>
<li>掛鉤、選擇性的掛鉤,以及選擇性的函式</li>
<li>過濾器、儲存區,及儲存區串列</li>
<li>模組</li>
</ul>第廿一章 編寫 Apache 的模組<br />
<ul><li>概要說明</li>
<li>狀態碼</li>
<li>模組結構</li>
<li>完整的範例</li>
<li>一般的提示</li>
<li>移植至 Apache 2.0</li>
</ul>附錄 Apache 1.x 的 API<br />
<br />
索引Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-46960341167010646852009-07-03T00:58:00.013+08:002009-09-08T23:48:20.657+08:00Apache Filter Module過濾器模組從應用模組程式開發的角度來看,Apache 2.x的最重要改進與創新就是<b>過濾器(filter)</b>的架構,過濾器使得處理不同的資料可以隨心所欲的運作。<div><br /></div><div>從Apache 2的架構來看,可以分為兩個正交軸,一為處理軸(Processing Axis),另一為資料軸(Data Axis)。每一次的請求皆由處理軸來接受,其中會經過許許多多的掛勾(hook),於是進行一些處理(handler)的呼叫。</div><div><br /></div><div>過濾器依據<b>過濾資料的處理階段</b>有這幾種不同類型:</div><div><ul><li><b>Content Filter</b>:在接受請求中,用來處理文件的資料。一般來說我們都式設計這類的過濾器居多,例如過濾HTML中特定的文字。</li><li><b>Protocol Filter</b>:用來處理通訊協定(protocol)的資料。在Apache中,Protocol Filter用在將HTTP通訊協定轉換request_rec的資料結構。</li><li><b>Connection Filter</b>:處理TCP連線的資料。用來處理conn_rec的資料結構,跟HTTP和request_recr皆無關係,你可以看成是操作在傳輸層(Transport Layer)的部分,而Content Filter和Protocol Filter是操作在應用層(Application Layer)。</li></ul></div>過濾器依據<b>放置的位置</b>則有這幾種不同類型:<div><ul><li><b>Input Filter</b>:處理來自client請求(request)的資料,故稱為輸入過濾器(Input Filter)。</li><li><b>Output Filter</b>:處理將回應(response)給client的資料,故稱為輸出過濾器(Output Filter)。</li></ul></div><div>此外,過濾器也有點像掛勾的樣子,有著另一種資料型態來處理過濾器之間的傳遞,是要依靠<b>ap_filter_t</b>的資料結構</div><div><br /></div><br /><pre class="brush:cpp"><br />/**<br /> * @brief The representation of a filter chain. <br /> *<br /> * Each request has a list<br /> * of these structures which are called in turn to filter the data. Sub<br /> * requests get an exact copy of the main requests filter chain.<br /> */<br />struct ap_filter_t {<br /> /** The internal representation of this filter. This includes<br /> * the filter's name, type, and the actual function pointer.<br /> */<br /> ap_filter_rec_t *frec;<br /><br /> /** A place to store any data associated with the current filter */<br /> void *ctx;<br /><br /> /** The next filter in the chain */<br /> ap_filter_t *next;<br /><br /> /** The request_rec associated with the current filter. If a sub-request<br /> * adds filters, then the sub-request is the request associated with the<br /> * filter.<br /> */<br /> request_rec *r;<br /><br /> /** The conn_rec associated with the current filter. This is analogous<br /> * to the request_rec, except that it is used for input filtering.<br /> */<br /> conn_rec *c;<br />};<br /></pre><br /><div>如果需要在多個過濾器之間傳送資料,你就需要用ctx這個資料欄位。</div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-90854969230870841852009-06-30T01:27:00.004+08:002009-06-30T01:51:54.294+08:00Apache WinNT MPM多執行模組的運作方式WinNT的MPM模組當中,使用一種稱為「<b>I/O Completion Ports</b>」的技術來處理各執行緒的請求分配,「I/O Completion Ports」中文稱為「I/O完全埠」、「I/O完成通訊埠」或「完成端口」等,也有簡稱<b>IOCP</b>。<div><br /></div><div>主要資料可以參考MSDN的兩個網址:</div><div><a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx">http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx</a></div><div><a href="http://www.microsoft.com/taiwan/technet/sysinternals/information/iocompletionports.mspx">http://www.microsoft.com/taiwan/technet/sysinternals/information/iocompletionports.mspx</a></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-60560154823622046812009-06-22T16:48:00.008+08:002009-07-11T11:37:25.499+08:00Apache MultiThread多執行緒寫法在WIN32的Apache中,<span class="blsp-spelling-error" id="SPELLING_ERROR_0">MPM</span>模組(多進程並發處理模塊)使用多執行緒來處理Request,其中避免單一資源被多個執行緒搶奪,必須使用一些技巧,可以參考<span class="blsp-spelling-error" id="SPELLING_ERROR_1">MSDN</span>中的<b>Synchronization Objects</b>主題文章(<a href="http://msdn.microsoft.com/en-us/library/ms686364(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms686364(VS.85).aspx</a>),常用的Synchronization Object有下列幾種:Event、<span class="blsp-spelling-error" id="SPELLING_ERROR_2">Mutex</span>、Semaphore和<span class="blsp-spelling-error" id="SPELLING_ERROR_3">Waitable</span> Timer。利用Synchronization Objects可以被指定給其中之一的<b>Wait Function</b>,讓這些Thread可以等等,如此避掉單一資源被多個執行緒搶奪。<div><br /></div><div>這些Object的特點如下:</div><div><ul><li>Event:用來通知一個或多個執行緒已經發生一件事情,詳見<a href="http://msdn.microsoft.com/en-us/library/ms682655(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms682655(VS.85).aspx</a></li><li><span class="blsp-spelling-error" id="SPELLING_ERROR_4">Mutex</span>:每一時間點只能被一個執行緒擁有此物件(<span class="blsp-spelling-error" id="SPELLING_ERROR_5">Mutex</span> Object),主要是用在多執行緒對共用資源的存取,可以達到執行緒互相唯一(Mutually Exclusive, Mut+Ex=Mutex)的操作方式。詳見<a href="http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspx</a></li><li>Semaphore:維持記數(count)在0和某一最大數值之間,用來限制同時存取共用資源的執行緒數量。詳見<a href="http://msdn.microsoft.com/en-us/library/ms685129(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms685129(VS.85).aspx</a></li><li><span class="blsp-spelling-error" id="SPELLING_ERROR_6">Waitable</span> Timer:設定一個或多個已經定時的執行緒,當時間到達時則通知這些執行緒。詳見<a href="http://msdn.microsoft.com/en-us/library/ms687012(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms687012(VS.85).aspx</a></li></ul><div>除了這四個物件之外,其他可以用來同步執行緒的物件還有:Change notification、Console input、Job、Memory resource notification、Process、Thread等。</div></div><div><div><br /></div><div>這裡還沒有提到一點,為了讓執行緒可以停下來等同步,我們必須使用Wait Function這個功能,Wait Function會在執行的時候block停止住,直到特定的條件(criteria)符合達成才會繼續執行下去,當然你也可以設定一段時間(time-out interval),當條件不符合時,進入等待的狀態,若時間超過則會繼續執行而不等待。</div><div><br /></div><div><br /></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-18851903028147437112009-06-12T12:15:00.007+08:002009-06-17T14:56:31.003+08:00Apache Platform平台運作說明當我在拆解Apache的同時,發現到一個不能忽略的問題,我們必須將視野提高到較高層次來觀看原始碼(source code),才不會見樹不見林,也較能對Apache的運作有深刻的體悟!樹、林是兩難。<div><br /></div><div>Apache HTTP Server(簡稱Apache)通常在作業系統啟動的時候,就會開始在背後執行,成為 Linux中的<b>Deamon</b>,或是Windows中的<b>Service</b>,有一件事:Apache在啟動的時候,是比較耗費系統資源,所以通常是OS啟動後就Apache提供服務,不太像一般程式,你要用到才去呼叫。</div><div><br /></div><div>Apache的程式當中分成兩個階段執行,一個是啟動階段(<b>start-up phase</b>),另一個是運行階段(<b>operational pahse</b>)。</div><div><br /></div><div>啟動階段(<b>start-up phase</b>)的作用有:讀取組態檔(httpd.conf或是.htaccess);載入各個模組(module);初始化系統資源,包含log檔、共享記憶體、資料連結等。</div><div><br /></div><div>啟動階段完成之後,進入運行階段(<b>operational pahse</b>),運行階段主要由MPM(Multi-Processing Module)模組接管控制,MPM會產生一個或多個的<b>執行緒池(Thread Pool)</b>或是行程(process),像Windows中只會有兩個process(即httpd.exe),其中之一是啟動階段的Master Process,另一個是運行階段的Child Process,由Child Process產生Thread Pool,此後由Thread Pool服務所有的Request請求。主要是因為Windows是支援Multi-Thread的作業系統。</div><div><br /></div><div><br /></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-6032101064408181392009-05-31T14:28:00.008+08:002009-09-08T23:54:49.531+08:00Request Processing in Apache 2.0請求的處理過程Apache中HTTP Request的程序主要是request.c中的函數來處理,這個函數是ap_process_request_internal,所有的請求都由它處理,包含子請求(subrequest)和轉向(redirect)。<div><br /></div><div>其程式碼如下所示:</div><br /><pre class="brush:cpp"><br />/* This is the master logic for processing requests. Do NOT duplicate<br />* this logic elsewhere, or the security model will be broken by future<br />* API changes. Each phase must be individually optimized to pick up<br />* redundant/duplicate calls by subrequests, and redirects.<br />*/<br />AP_DECLARE(int) ap_process_request_internal(request_rec *r)<br />{<br /> int file_req = (r->main && r->filename);<br /> int access_status;<br /><br /> /* Ignore embedded %2F's in path for proxy requests */<br /> if (!r->proxyreq && r->parsed_uri.path) {<br /> core_dir_config *d;<br /> d = ap_get_module_config(r->per_dir_config, &core_module);<br /> if (d->allow_encoded_slashes) {<br /> access_status = ap_unescape_url_keep2f(r->parsed_uri.path);<br /> }<br /> else {<br /> access_status = ap_unescape_url(r->parsed_uri.path);<br /> }<br /> if (access_status) {<br /> if (access_status == HTTP_NOT_FOUND) {<br /> if (! d->allow_encoded_slashes) {<br /> ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,<br /> "found %%2f (encoded '/') in URI "<br /> "(decoded='%s'), returning 404",<br /> r->parsed_uri.path);<br /> }<br /> }<br /> return access_status;<br /> }<br /> }<br /><br /> ap_getparents(r->uri); /* OK --- shrinking transformations... */<br /><br /> /* All file subrequests are a huge pain... they cannot bubble through the<br /> * next several steps. Only file subrequests are allowed an empty uri,<br /> * otherwise let translate_name kill the request.<br /> */<br /> if (!file_req) {<br /> if ((access_status = ap_location_walk(r))) {<br /> return access_status;<br /> }<br /><br /> if ((access_status = ap_run_translate_name(r))) {<br /> return decl_die(access_status, "translate", r);<br /> }<br /> }<br /><br /> /* Reset to the server default config prior to running map_to_storage<br /> */<br /> r->per_dir_config = r->server->lookup_defaults;<br /><br /> if ((access_status = ap_run_map_to_storage(r))) {<br /> /* This request wasn't in storage (e.g. TRACE) */<br /> return access_status;<br /> }<br /><br /> /* Rerun the location walk, which overrides any map_to_storage config.<br /> */<br /> if ((access_status = ap_location_walk(r))) {<br /> return access_status;<br /> }<br /><br /> /* Only on the main request! */<br /> if (r->main == NULL) {<br /> if ((access_status = ap_run_header_parser(r))) {<br /> return access_status;<br /> }<br /> }<br /><br /> /* Skip authn/authz if the parent or prior request passed the authn/authz,<br /> * and that configuration didn't change (this requires optimized _walk()<br /> * functions in map_to_storage that use the same merge results given<br /> * identical input.) If the config changes, we must re-auth.<br /> */<br /> if (r->main && (r->main->per_dir_config == r->per_dir_config)) {<br /> r->user = r->main->user;<br /> r->ap_auth_type = r->main->ap_auth_type;<br /> }<br /> else if (r->prev && (r->prev->per_dir_config == r->per_dir_config)) {<br /> r->user = r->prev->user;<br /> r->ap_auth_type = r->prev->ap_auth_type;<br /> }<br /> else {<br /> switch (ap_satisfies(r)) {<br /> case SATISFY_ALL:<br /> case SATISFY_NOSPEC:<br /> if ((access_status = ap_run_access_checker(r)) != 0) {<br /> return decl_die(access_status, "check access", r);<br /> }<br /><br /> if (ap_some_auth_required(r)) {<br /> if (((access_status = ap_run_check_user_id(r)) != 0)<br /> || !ap_auth_type(r)) {<br /> return decl_die(access_status, ap_auth_type(r)<br /> ? "check user. No user file?"<br /> : "perform authentication. AuthType not set!",<br /> r);<br /> }<br /><br /> if (((access_status = ap_run_auth_checker(r)) != 0)<br /> || !ap_auth_type(r)) {<br /> return decl_die(access_status, ap_auth_type(r)<br /> ? "check access. No groups file?"<br /> : "perform authentication. AuthType not set!",<br /> r);<br /> }<br /> }<br /> break;<br /><br /> case SATISFY_ANY:<br /> if (((access_status = ap_run_access_checker(r)) != 0)) {<br /> if (!ap_some_auth_required(r)) {<br /> return decl_die(access_status, "check access", r);<br /> }<br /><br /> if (((access_status = ap_run_check_user_id(r)) != 0)<br /> || !ap_auth_type(r)) {<br /> return decl_die(access_status, ap_auth_type(r)<br /> ? "check user. No user file?"<br /> : "perform authentication. AuthType not set!",<br /> r);<br /> }<br /><br /> if (((access_status = ap_run_auth_checker(r)) != 0)<br /> || !ap_auth_type(r)) {<br /> return decl_die(access_status, ap_auth_type(r)<br /> ? "check access. No groups file?"<br /> : "perform authentication. AuthType not set!",<br /> r);<br /> }<br /> }<br /> break;<br /> }<br /> }<br /> /* XXX Must make certain the ap_run_type_checker short circuits mime<br /> * in mod-proxy for r->proxyreq && r->parsed_uri.scheme<br /> * && !strcmp(r->parsed_uri.scheme, "http")<br /> */<br /> if ((access_status = ap_run_type_checker(r)) != 0) {<br /> return decl_die(access_status, "find types", r);<br /> }<br /><br /> if ((access_status = ap_run_fixups(r)) != 0) {<br /> return access_status;<br /> }<br /><br /> return OK;<br />}<br /></pre>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-49876594176062527832009-05-25T00:44:00.007+08:002009-05-31T02:11:34.628+08:00Apache Portable Runtime可移植執行環境Apache HTTP Server運作時需要依賴另一個程式庫,也就是APR,全名為「Apache Portable Runtime可移植執行環境」,這其實是Apache Software Foundation(ASF)底下另一個專案計畫,請參考<a href="http://apr.apache.org/">http://apr.apache.org/</a><div><br /></div><div></div><span><span></span></span><span><span></span></span><span><span>APR中有一項重要的程式庫模組,這個模組是APR Pools(apr_pools.h),這是APR和Apchee中管理資源的重要模組!其資料型態是apr_poot_t。在APR當中則是Memory Pool Functions這個模組裡面,原始碼是memory\apr_pools.c,他主要功能其實也就是記憶體管理!<br /></span></span><div><br /></div><div>其他定義如下(ver 1.3)</div><span><span>Defines</span></span><div><ul><li>#define APR_POOL_DECLARE_ACCESSOR(type) </li><li>#define APR_POOL_IMPLEMENT_ACCESSOR(type)</li><li>#define APR_POOL_DEBUG 0</li><li>#define APR_POOL__FILE_LINE__ __FILE__ ":" APR_STRINGIFY(__LINE__) </li></ul></div><div><span><span><br /></span></span></div><div><span><span>Typedefs</span></span></div><div><ul><li>typedef struct apr_pool_t apr_pool_t</li><li>typedef int(* apr_abortfunc_t )(int retcode) </li></ul></div><div><span><span><br />Functions</span></span></div><div><ul><li>apr_status_t <b>apr_pool_initialize</b> (void)</li><li>void <b>apr_pool_terminate</b> (void)</li><li>apr_status_t <b>apr_pool_create_ex</b> (apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator)</li><li>apr_status_t <b>apr_pool_create_core_ex</b> (apr_pool_t **newpool, apr_abortfunc_t abort_fn, apr_allocator_t *allocator)</li><li>apr_status_t <b>apr_pool_create_unmanaged_ex</b> (apr_pool_t **newpool, apr_abortfunc_t abort_fn, apr_allocator_t *allocator)</li><li>apr_status_t <b>apr_pool_create_ex_debug</b> (apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, const char *file_line)</li><li>apr_status_t <b>apr_pool_create_core_ex_debug</b> (apr_pool_t **newpool, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, const char *file_line)</li><li>apr_status_t <b>apr_pool_create_unmanaged_ex_debug</b> (apr_pool_t **newpool, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, const char *file_line)</li><li>apr_status_t <b>apr_pool_create</b> (apr_pool_t **newpool, apr_pool_t *parent)</li><li>apr_status_t <b>apr_pool_create_core </b>(apr_pool_t **newpool)</li><li>apr_status_t <b>apr_pool_create_unmanaged</b> (apr_pool_t **newpool)</li><li>apr_allocator_t * <b>apr_pool_allocator_get</b> (apr_pool_t *pool)</li><li>void <b>apr_pool_clear</b> (apr_pool_t *p)</li><li>void <b>apr_pool_clear_debug</b> (apr_pool_t *p, const char *file_line)</li><li>void <b>apr_pool_destroy</b> (apr_pool_t *p)</li><li>void <b>apr_pool_destroy_debug</b> (apr_pool_t *p, const char *file_line)</li><li>void * <b>apr_palloc</b> (apr_pool_t *p, apr_size_t size)</li><li>void * <b>apr_palloc_debug</b> (apr_pool_t *p, apr_size_t size, const char *file_line)</li><li>void * <b>apr_pcalloc</b> (apr_pool_t *p, apr_size_t size)</li><li>void * <b>apr_pcalloc_debug</b> (apr_pool_t *p, apr_size_t size, const char *file_line)</li><li>void <b>apr_pool_abort_set</b> (apr_abortfunc_t abortfunc, apr_pool_t *pool)</li><li>apr_abortfunc_t <b>apr_pool_abort_get</b> (apr_pool_t *pool)</li><li>apr_pool_t * <b>apr_pool_parent_get</b> (apr_pool_t *pool)</li><li>int <b>apr_pool_is_ancestor</b> (apr_pool_t *a, apr_pool_t *b)</li><li>void <b>apr_pool_tag</b> (apr_pool_t *pool, const char *tag)</li><li>apr_status_t <b>apr_pool_userdata_set</b> (const void *data, const char *key, apr_status_t(*cleanup)(void *), apr_pool_t *pool)</li><li>apr_status_t <b>apr_pool_userdata_setn</b> (const void *data, const char *key, apr_status_t(*cleanup)(void *), apr_pool_t *pool)</li><li>apr_status_t <b>apr_pool_userdata_get</b> (void **data, const char *key, apr_pool_t *pool)</li></ul><div><br /></div></div><div><div></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-87612179675861504462009-05-24T19:49:00.004+08:002009-05-24T21:06:07.479+08:00Request in Apache請求處理的流程我們必須先知道一件事,使用者的<span class="Apple-style-span" style="font-weight: bold;">瀏覽器(browser)</span>向Apache伺服器請求資料時,必須先建立TPC連線,依照HTTP通訊協定的規範向Apache伺服器請求資料。也就是說,Aapche處理請求的流程可以分為:建立TPC連線<span class="Apple-style-span" style="font-weight: bold;">之前</span>、建立TPC連線<span class="Apple-style-span" style="font-weight: bold;">之後</span>(開始用HTTP),這兩個部分。<div><br /></div><div>請求處理的流程</div><div><ol><li>接收請求(Accept Request)<br /></li><li>中繼資料處理(Metadata Processing),request會傳遞很多個掛勾(hook),呼叫所屬階段的<span class="Apple-style-span" style="font-weight: bold;">程序(function)</span>。</li><li>產生回應內容(Content Generator)</li><li>記錄(Logging)</li></ol><div>正常來說,大致上是依據這個流程,如果是錯誤(error)或是產生新請求,則有可能使得request導向其他程序,另外,每個程序也可以讓其他程序呼叫,簡言之,有點複雜!(應該要畫圖解釋...)</div><div><br /></div><div>處理的流程當中,Apache提供<span class="Apple-style-span" style="font-weight: bold;">掛勾(hook)</span>這項功能,可讓我們開發應用模組(module)的時候,利用回呼(callback)的方式值型模組中的功能。掛勾的總類依照請求的先後順序為:</div><div><ol><li>ap_hook_post_read_request<br /></li><li>ap_hook_translate_name<br /></li><li>ap_hook_map_to_storage<br /></li><li>ap_hook_header_parser<br /></li><li>ap_hook_access_checker<br /></li><li>ap_hook_check_user_id<br /></li><li>ap_hook_auth_checker<br /></li><li>ap_hook_type_checker<br /></li><li>ap_hook_fixups<br /></li><li>ap_hook_handler<br /></li><li>ap_hook_log_transaction<br /></li></ol></div><div>最後,Apache預設處理請求的程式是掛在ap_hook_handler之中,其函數原形為<span class="Apple-style-span" style="font-weight: bold;">static int default_handler(request_rec *r)</span>,位於server\core.c檔案當中。</div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-25082818964038206532009-05-23T16:59:00.007+08:002009-05-29T01:29:43.645+08:00Apache Core Objects主要物件Apache程式碼定義了一些結構可以使用,其中有四個結構相當重要,會在開發應用程式模組中使用到,主要是定義在httpd.h這個標頭檔中,其結構名稱有:<div><div><ul><li><span class="Apple-style-span" style="color: rgb(255, 102, 0);">request_rec</span>每個請求的相關資訊<br /></li><li><span class="Apple-style-span" style="color: rgb(0, 153, 0);">server_rec</span>每個主機的相關資訊<br /></li><li><span class="Apple-style-span" style="color: rgb(51, 51, 255);">conn_rec</span>每次連線的相關資訊<br /></li><li><span class="Apple-style-span" style="color: rgb(153, 51, 153);">process_rec</span>每個程序的相關資訊<br /></li></ul></div><div>詳細程式碼如下:<br /></div><div><br /></div><div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);">struct request_rec {<br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The pool associated with the request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_pool_t *pool;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The connection to the client */</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> conn_rec *connection;</span></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The virtual host for this request */</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> server_rec *server;</span></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Pointer to the redirected request if this is an external redirect */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> request_rec *next;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Pointer to the previous request if this is an internal redirect */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> request_rec *prev;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Pointer to the main request if this is a sub-request</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * (see http_request.h) */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> request_rec *main;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* Info about the request itself... we begin with stuff that only</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * protocol.c should ever touch...</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** First line of request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *the_request;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** HTTP/0.9, "simple" request (e.g. GET /foo\n w/no headers) */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int assbackwards;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A proxy request (calculated during post_read_request/translate_name)</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * possible values PROXYREQ_NONE, PROXYREQ_PROXY, PROXYREQ_REVERSE,</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * PROXYREQ_RESPONSE</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int proxyreq;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** HEAD request, as opposed to GET */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int header_only;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Protocol string, as given to us, or HTTP/0.9 */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *protocol;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Protocol version number of protocol; 1.1 = 1001 */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int proto_num;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Host, as set by full URI or Host: */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *hostname;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Time when the request started */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_time_t request_time;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Status line, if set by script */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *status_line;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Status line */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int status;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* Request method, two ways; also, protocol, etc.. Outside of protocol.c,</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * look, but don't touch.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Request method (eg. GET, HEAD, POST, etc.) */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *method;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** M_GET, M_POST, etc. */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int method_number;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /**</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * 'allowed' is a bitvector of the allowed methods.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> *</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * A handler must ensure that the request method is one that</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * it is capable of handling. Generally modules should DECLINE</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * any request methods they do not handle. Prior to aborting the</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * handler like this the handler should set r->allowed to the list</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * of methods that it is willing to handle. This bitvector is used</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * to construct the "Allow:" header required for OPTIONS requests,</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * and HTTP_METHOD_NOT_ALLOWED and HTTP_NOT_IMPLEMENTED status codes.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> *</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * Since the default_handler deals with OPTIONS, all modules can</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * usually decline to deal with OPTIONS. TRACE is always allowed,</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * modules don't need to set it explicitly.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> *</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * Since the default_handler will always handle a GET, a</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * module which does *not* implement GET should probably return</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * HTTP_METHOD_NOT_ALLOWED. Unfortunately this means that a Script GET</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * handler can't be installed by mod_actions.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_int64_t allowed;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Array of extension methods */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_array_header_t *allowed_xmethods; </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** List of allowed methods */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> ap_method_list_t *allowed_methods; </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** byte count in stream is for body */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_off_t sent_bodyct;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** body byte count, for easy access */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_off_t bytes_sent;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Last modified time of the requested resource */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_time_t mtime;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* HTTP/1.1 connection-level features */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** sending chunked transfer-coding */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int chunked;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The Range: header */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *range;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The "real" content length */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_off_t clength;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Remaining bytes left to read from the request body */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_off_t remaining;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Number of bytes that have been read from the request body */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_off_t read_length;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Method for reading the request body</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * (eg. REQUEST_CHUNKED_ERROR, REQUEST_NO_BODY,</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * REQUEST_CHUNKED_DECHUNK, etc...) */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int read_body;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** reading chunked transfer-coding */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int read_chunked;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** is client waiting for a 100 response? */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> unsigned expecting_100;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* MIME header environments, in and out. Also, an array containing</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * environment variables to be passed to subprocesses, so people can</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * write modules to add to that environment.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> *</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * The difference between headers_out and err_headers_out is that the</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * latter are printed even on error, and persist across internal redirects</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * (so the headers printed for ErrorDocument handlers will have them).</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> *</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * The 'notes' apr_table_t is for notes from one module to another, with no</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * other set purpose in mind...</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** MIME header environment from the request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_table_t *headers_in;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** MIME header environment for the response */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_table_t *headers_out;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** MIME header environment for the response, printed even on errors and</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * persist across internal redirects */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_table_t *err_headers_out;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Array of environment variables to be used for sub processes */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_table_t *subprocess_env;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Notes from one module to another */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_table_t *notes;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* content_type, handler, content_encoding, and all content_languages </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * MUST be lowercased strings. They may be pointers to static strings;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * they should not be modified in place.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The content-type for the current request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *content_type;</span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></span><span class="Apple-style-span" style="color: rgb(255, 102, 0);">/* Break these out --- we dispatch on 'em */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The handler string that we use to call a handler function */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *handler;</span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></span><span class="Apple-style-span" style="color: rgb(255, 102, 0);">/* What we *really* dispatch on */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** How to encode the data */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const char *content_encoding;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Array of strings representing the content languages */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_array_header_t *content_languages;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** variant list validator (if negotiated) */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *vlist_validator;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** If an authentication check was made, this gets set to the user name. */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *user;</span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** If an authentication check was made, this gets set to the auth type. */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *ap_auth_type;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** This response can not be cached */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int no_cache;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** There is no local copy of this response */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int no_local_copy;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* What object is being requested (either directly, or via include</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * or content-negotiation mapping).</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The URI without any parsing performed */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *unparsed_uri;</span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The path portion of the URI */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *uri;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The filename on disk corresponding to this response */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *filename;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* XXX: What does this mean? Please define "canonicalize" -aaron */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The true filename, we canonicalize r->filename if these don't match */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *canonical_filename;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The PATH_INFO extracted from this request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *path_info;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** The QUERY_ARGS extracted from this request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> char *args;</span><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> </span></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** finfo.protection (st_mode) set to zero if no such file */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_finfo_t finfo;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A struct containing the components of URI */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> apr_uri_t parsed_uri;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /**</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * Flag for the handler to accept or reject path_info on </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * the current request. All modules should respect the</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * AP_REQ_ACCEPT_PATH_INFO and AP_REQ_REJECT_PATH_INFO </span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * values, while AP_REQ_DEFAULT_PATH_INFO indicates they</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * may follow existing conventions. This is set to the</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * user's preference upon HOOK_VERY_FIRST of the fixups.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int used_path_info;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /* Various other config info which may change with .htaccess files</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * These are config vectors, with one void* pointer for each module</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * (the thing pointed to being the module's business).</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Options set in config files, etc. */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_conf_vector_t *per_dir_config;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** Notes on *this* request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_conf_vector_t *request_config;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /**</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * A linked list of the .htaccess configuration directives</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * accessed by this request.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * N.B. always add to the head of the list, _never_ to the end.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * that way, a sub request's list can (temporarily) point to a parent's list</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> const struct htaccess_result *htaccess;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A list of output filters to be used for this request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_filter_t *output_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A list of input filters to be used for this request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_filter_t *input_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A list of protocol level output filters to be used for this</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_filter_t *proto_output_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A list of protocol level input filters to be used for this</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * request */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> struct ap_filter_t *proto_input_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> /** A flag to determine if the eos bucket has been sent yet */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> int eos_sent;</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);">/* Things placed at the end of the record to avoid breaking binary</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * compatibility. It would be nice to remember to reorder the entire</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * record to improve 64bit alignment the next time we need to break</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> * binary compatibility for some other reason.</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(255, 102, 0);">};</span></div><div><br /></div><div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">struct server_rec {</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The process this server is running in */這個伺服器正在執行的行程,也許是虛擬伺服器</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> process_rec *process;</span></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The next server in the list */位於清單中,下一個伺服器組態</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> server_rec *next;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The name of the server */這個伺服器的名子</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> const char *defn_name;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The line of the config file that the server was defined on */組態檔httpd.conf中,定義伺服器的行號</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> unsigned defn_line_number;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /* Contact information */</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The admin's contact information */管理員的聯絡資訊(電子信箱)</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> char *server_admin;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The server hostname */這個伺服器的主機名稱</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> char *server_hostname;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** for redirects, etc. */用於重新導向,埠號</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_port_t port;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /* Log files --- note that transfer log is now in the modules... */</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The name of the error log */錯誤記錄檔的名稱</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> char *error_fname;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** A file descriptor that references the error log */指標,指向錯誤記錄檔</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_file_t *error_log;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The log level for this server */記錄檔記錄的層次</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int loglevel;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /* Module-specific configuration for server, and defaults... */</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** true if this is the virtual server */是否是虛擬伺服器</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int is_virtual;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Config vector containing pointers to modules' per-server config </span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> * structures. */指向伺服器組態的向量</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> struct ap_conf_vector_t *module_config; </span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** MIME type info, etc., before we start checking per-directory info */MIME型態資訊</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> struct ap_conf_vector_t *lookup_defaults;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /* Transaction handling */</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** I haven't got a clue */<span class="Apple-style-span" style="font-weight: bold;">還不知道這是什麼!</span></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> server_addr_rec *addrs;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Timeout, as an apr interval, before we give up */逾時時間</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_interval_time_t timeout;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The apr interval we will wait for another request */持續連線的逾時時間</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_interval_time_t keep_alive_timeout;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Maximum requests per connection */每個連線的最大請求數目</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int keep_alive_max;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Use persistent connections? */是否使用http的持續連線</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int keep_alive;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Pathname for ServerPath */伺服器路徑的名稱</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> const char *path;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Length of path */路徑長度</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int pathlen;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Normal names for ServerAlias servers */別名伺服器的正常名稱</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_array_header_t *names;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** Wildcarded names for ServerAlias servers */別名伺服器的萬用名稱</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> apr_array_header_t *wild_names;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** limit on size of the HTTP request line */請求的行數限制</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int limit_req_line;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** limit on size of any request header field */請求標頭欄位大小的限制</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int limit_req_fieldsize;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** limit on number of request header fields */請求標頭欄位數目的限制</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> int limit_req_fields; </span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> /** The server request scheme for redirect responses */重新導向的請求方法</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> const char *server_scheme;</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">};</span></div><div><br /></div><div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">struct conn_rec {</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Pool associated with this connection */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> apr_pool_t *pool;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Physical vhost this conn came in on */</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(0, 153, 0);"> server_rec *base_server;</span></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** used by http_vhost.c */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> void *vhost_lookup_data;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /* Information about the connection itself */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** local address */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> apr_sockaddr_t *local_addr;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** remote address */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> apr_sockaddr_t *remote_addr;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Client's IP address */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> char *remote_ip;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Client's DNS name, if known. NULL if DNS hasn't been checked,</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * "" if it has and no address was found. N.B. Only access this though</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * get_remote_host() */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> char *remote_host;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Only ever set if doing rfc1413 lookups. N.B. Only access this through</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * get_remote_logname() */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> char *remote_logname;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Are we still talking? */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> unsigned aborted:1;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Are we going to keep the connection alive for another request?</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * @see ap_conn_keepalive_e */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> ap_conn_keepalive_e keepalive;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** have we done double-reverse DNS? -1 yes/failure, 0 not yet, </span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * 1 yes/success */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> signed int double_reverse:2;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** How many times have we used it? */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> int keepalives;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** server IP address */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> char *local_ip;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** used for ap_get_server_name when UseCanonicalName is set to DNS</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * (ignores setting of HostnameLookups) */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> char *local_host;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** ID of this connection; unique at any point in time */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> long id; </span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Config vector containing pointers to connections per-server</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * config structures. */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> struct ap_conf_vector_t *conn_config;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Notes on *this* connection: send note from one module to</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * another. must remain valid for all requests on this conn */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> apr_table_t *notes;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** A list of input filters to be used for this connection */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> struct ap_filter_t *input_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** A list of output filters to be used for this connection */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> struct ap_filter_t *output_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** handle to scoreboard information for this connection */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> void *sbh;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** The bucket allocator to use for all bucket/brigade creations */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> struct apr_bucket_alloc_t *bucket_alloc;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** The current state of this connection */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> conn_state_t *cs;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Is there data pending in the input filters? */ </span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> int data_in_input_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> </span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> /** Are there any filters that clogg/buffer the input stream, breaking</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> * the event mpm.</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> */</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);"> int clogging_input_filters;</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">};</span></div><div><br /></div><div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);">struct process_rec {</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> /** Global pool. Cleared upon normal exit */</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> apr_pool_t *pool;</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> /** Configuration pool. Cleared upon restart */</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> apr_pool_t *pconf;</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> /** Number of command line arguments passed to the program */</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> int argc;</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> /** The command line arguments */</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> const char * const *argv;</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> /** The program name used to execute the program */</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);"> const char *short_name;</span></div><div><span class="Apple-style-span" style="color: rgb(153, 51, 153);">};</span></div></div></div></div><div><br /></div></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-51306688744272394462009-05-23T12:14:00.006+08:002009-05-24T00:30:25.771+08:00Apache Multi-Processing Modules多行程模組<div>MPM是Apache中的一個模組,全名為Multi-Processing Module<span class="Apple-style-span" style="font-weight: bold;">多行程模組</span>,這個模組是介於APR和底層的作業系統(Operation System, OS)的一個模組,其目的是用來最佳化,使得Apache在各式的OS上能有傑出的效能表現。<br /></div><div><br />MPM本身是系統層級(system-level)的模組,意思就是說,開發上和其他模組會不一樣,哪裡不一樣?目前還在研究當中。不過,我們大多數的應用只會按照一般模組的樣子來開發,絕大多數都是這種開發方式(即非系統層級)。</div><div><br /></div><div>早期Apache發展在UNIX之類的作業系統上,這類系統多為多處理器的伺服器,而作業系統會依照請求(request)<span class="Apple-style-span" style="font-weight: bold;">分岔(fork)</span>產生其他行程(process)來處理,一般來說,Apache啟動的時候,會產生一個<span class="Apple-style-span" style="font-weight: bold;">集散區</span>(pool,也有稱為"池")來管理這些行程。之後2.0版本,為了能夠跨平台(cross-platform)的高效率、最佳化運作,所以才設計出MPM這個模組。</div><div><br /></div><div>實務應用上來說,只有UNIX之類的作業系統有較多的設定可供選擇使用。我目前是以windows開發,真的選項就只有兩個可以設定:<span class="Apple-style-span" style="font-weight: bold;">MaxRequestsPerChild</span>和<span class="Apple-style-span" style="font-weight: bold;">ThreadsPerChild</span>兩個指令。其他指令請參考<a href="http://httpd.apache.org/docs/2.2/mod/mpm_common.html">http://httpd.apache.org/docs/2.2/mod/mpm_common.html</a></div><div><br /></div><div>在MPM這個部分當中,因為跟底層OS有密切關係,其實MPM有好幾個類別,有些是給UNIX用的,有些是給Windows(WIN32)用的,有些則給其他OS用的,所以再看這些指令的時候,必須注意它所依賴的模組,否則社定會失敗。另一個問題是,我們可以選擇使用哪個MPM嗎?應該是不行,除非你自己重新complie一次,MPM的設定在編譯Apache時就已經決定了!</div><div><br /></div><div>以UNIX這群的MPM來說,有Prefork MPM、Worker MPM以及正在試驗的Event MPM。</div><div><ul><li>Prefork MPM是非執行緒的架構,和以往1版的類似。<br /></li><li>Worker MPM是多執行緒的架構,其執行緒和每個請求連線有關。<br /></li><li>Event MPM是正在試驗當中,將執行緒與請求連線的關係解耦合,可以避免請求連線超出執行緒的問題。<br /></li></ul></div><div>結論:開發Apache的模組、應用程式來說,不需要理會MPM,請忽略MPM這個模組!</div><div><br /></div><div>我目前以windows開發,所以主要是專注於mpm_winnt,其指令Directives有</div><div><div><ul><li>CoreDumpDirectory<br /></li><li>Listen<br /></li><li>ListenBacklog<br /></li><li>MaxMemFree<br /></li><li>MaxRequestsPerChild<br /></li><li>PidFile<br /></li><li>ReceiveBufferSize<br /></li><li>ScoreBoardFile<br /></li><li>SendBufferSize<br /></li><li>ThreadLimit<br /></li><li>ThreadsPerChild<br /></li><li>ThreadStackSize<br /></li><li>Win32DisableAcceptEx<br /></li></ul></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-17039666026290117692009-05-22T17:11:00.015+08:002009-09-09T00:26:47.634+08:00Deconstruction of Apache Code解構阿帕契程式碼太久,真的是一個月沒有更新部落格。忙著,也跟著茫了。<div><br /></div><div>目前正在使用Apache Http Server的程式撰寫。我想之後會寫有關於Apache的程式碼內容,希望有這個能力和空閒時間。(忙著活下去,還有時間嗎!好問題~)</div><div><br /></div><div>先講參考書籍,討論Apache的書籍很少(手指頭的數目之內),中文可以參考下面這本:</div><div><table style="width:auto;"><tbody><tr><td><a href="http://picasaweb.google.com/lh/photo/rlZkp--cVURbSdzdc91OKA?authkey=Gv1sRgCNmhtYCEnOy04AE&feat=embedwebsite"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV6KrQpPZop5htEy4470mWydp_uP7kby1hCICNzhyphenhyphena_0MjAR1k3aP6ewNGJ31z3tZmMn29dV1x0-PzyZYSQ6sTqNO0VZ4d4h77RobmLTjdJwVRg8VS5roVR_A0CMpmiwU56iMfSUD8F5w/s400/Picture%2053.jpg" /></a></td></tr></tbody></table></div><div>Ben Laurie & Peter Laurie原著,郭文生編譯,Apache技術手冊(第三版),台北:歐萊禮,2003。</div><div><br /></div><div>怎麼開始呢?Deconstruction,解構。應該不稱之為解構主義,一方面我現在不了解何謂解構主義,只是想將Apache的Code<span class="Apple-style-span" style="font-weight: bold;">猜(拆)</span>解開來看看,這套軟體的運作方式?我們有沒有能力做出這樣的軟體呢?需要哪些能力和人力?如何設計更是大問題!(我的疑問)</div><div><br /></div><div><div>Apache的進入點是main.c,在httpd這個專案(Project)裡面,程式碼架構如下:</div><div><br /></div><div>用到的標頭檔,Apache底層是Apache Portability Runtime(APR),因此會引入許多apr_的header file,而基於APR建置的程式庫則有APR-util,簡稱APU,以及實現iconv()的APR-iconv。另外,http_是關於http protocol的一些處理,也需要因引入。</div><div><br /></div><div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr.h" //平台定義</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_strings.h" //字串處理程式庫</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_getopt.h" //命令參數</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_general.h" //混雜的程式庫,未歸類的</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_lib.h" //通用程式庫</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_md5.h" //md5的程式庫,屬於APU</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_time.h" //時間程式庫</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_version.h" //APR的版本介面</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apu_version.h" //APU的版本介面</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#define APR_WANT_STDIO</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#define APR_WANT_STRFUNC</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_want.h" //APR對於標準標頭檔支援</span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);"><br /></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#define CORE_PRIVATE</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "ap_config.h" //定義掛勾hook的標頭檔</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "httpd.h" //主要基本的定義</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "http_main.h" //main程式的定義</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "http_log.h" //記錄檔的定義</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "http_config.h" //一些設定的定義</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "http_core.h" //核心模組的定義</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "http_vhost.h" //虛擬主機的定義</span></span></span></div><div><span class="Apple-style-span" style="color: rgb(0, 153, 0);">#include "apr_uri.h" //uri的程式庫,屬於APU</span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "util_ebcdic.h" //定義</span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">Extended Binary Coded Decimal Interchange Code(</span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">EBCDIC)的轉換功能</span></span></span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "ap_mpm.h" //定義Multi-Processing Module(MPM),多處理模組</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(255, 102, 0);">#include "mpm_common.h" //MPM用的程式庫</span></span></span></div><div><br /></div><div>定義到的函數(function):</div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">static void show_mpm_settings(void)<br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">static void show_compile_settings(void)<br /></span></div><div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">static void destroy_and_exit_process(process_rec *process, int process_exit_value)</span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">static process_rec *init_process(int *argc, const char * const * *argv)<br /></span></div><div><span class="Apple-style-span" style="color: rgb(51, 51, 255);">static void usage(process_rec *process)</span><br /></div><div><br /></div><div>主程式碼:</div><div><br /><pre class="brush:cpp"><br />int main(int argc, const char * const argv[])<br />{<br /> char c;<br /> int configtestonly = 0;<br /> const char *confname = SERVER_CONFIG_FILE;<br /> const char *def_server_root = HTTPD_ROOT;<br /> const char *temp_error_log = NULL;<br /> const char *error;<br /> process_rec *process;<br /> server_rec *server_conf;<br /> apr_pool_t *pglobal;<br /> apr_pool_t *pconf;<br /> apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */<br /> apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */<br /> apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */<br /> apr_getopt_t *opt;<br /> apr_status_t rv;<br /> module **mod;<br /> const char *optarg;<br /> APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;<br /><br /> AP_MONCONTROL(0); /* turn off profiling of startup */<br /><br /> process = init_process(&argc, &argv);<br /> pglobal = process->pool;<br /> pconf = process->pconf;<br /> ap_server_argv0 = process->short_name;<br /><br />#if APR_CHARSET_EBCDIC<br /> if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {<br /> destroy_and_exit_process(process, 1);<br /> }<br />#endif<br /><br /> apr_pool_create(&pcommands, pglobal);<br /> apr_pool_tag(pcommands, "pcommands");<br /> ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *));<br /> ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));<br /> ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *));<br /><br /> error = ap_setup_prelinked_modules(process);<br /> if (error) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, "%s: %s",<br /> ap_server_argv0, error);<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> ap_run_rewrite_args(process);<br /><br /> /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM<br /> * to safely pass on our args from its rewrite_args() handler.<br /> */<br /> apr_getopt_init(&opt, pcommands, process->argc, process->argv);<br /><br /> while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))<br /> == APR_SUCCESS) {<br /> char **new;<br /><br /> switch (c) {<br /> case 'c':<br /> new = (char **)apr_array_push(ap_server_post_read_config);<br /> *new = apr_pstrdup(pcommands, optarg);<br /> break;<br /><br /> case 'C':<br /> new = (char **)apr_array_push(ap_server_pre_read_config);<br /> *new = apr_pstrdup(pcommands, optarg);<br /> break;<br /><br /> case 'd':<br /> def_server_root = optarg;<br /> break;<br /><br /> case 'D':<br /> new = (char **)apr_array_push(ap_server_config_defines);<br /> *new = apr_pstrdup(pcommands, optarg);<br /> /* Setting -D DUMP_VHOSTS is equivalent to setting -S */<br /> if (strcmp(optarg, "DUMP_VHOSTS") == 0)<br /> configtestonly = 1;<br /> /* Setting -D DUMP_MODULES is equivalent to setting -M */<br /> if (strcmp(optarg, "DUMP_MODULES") == 0)<br /> configtestonly = 1;<br /> break;<br /><br /> case 'e':<br /> if (strcasecmp(optarg, "emerg") == 0) {<br /> ap_default_loglevel = APLOG_EMERG;<br /> }<br /> else if (strcasecmp(optarg, "alert") == 0) {<br /> ap_default_loglevel = APLOG_ALERT;<br /> }<br /> else if (strcasecmp(optarg, "crit") == 0) {<br /> ap_default_loglevel = APLOG_CRIT;<br /> }<br /> else if (strncasecmp(optarg, "err", 3) == 0) {<br /> ap_default_loglevel = APLOG_ERR;<br /> }<br /> else if (strncasecmp(optarg, "warn", 4) == 0) {<br /> ap_default_loglevel = APLOG_WARNING;<br /> }<br /> else if (strcasecmp(optarg, "notice") == 0) {<br /> ap_default_loglevel = APLOG_NOTICE;<br /> }<br /> else if (strcasecmp(optarg, "info") == 0) {<br /> ap_default_loglevel = APLOG_INFO;<br /> }<br /> else if (strcasecmp(optarg, "debug") == 0) {<br /> ap_default_loglevel = APLOG_DEBUG;<br /> }<br /> else {<br /> usage(process);<br /> }<br /> break;<br /><br /> case 'E':<br /> temp_error_log = apr_pstrdup(process->pool, optarg);<br /> break;<br /><br /> case 'X':<br /> new = (char **)apr_array_push(ap_server_config_defines);<br /> *new = "DEBUG";<br /> break;<br /><br /> case 'f':<br /> confname = optarg;<br /> break;<br /><br /> case 'v':<br /> printf("Server version: %s\n", ap_get_server_description());<br /> printf("Server built: %s\n", ap_get_server_built());<br /> destroy_and_exit_process(process, 0);<br /><br /> case 'V':<br /> show_compile_settings();<br /> destroy_and_exit_process(process, 0);<br /><br /> case 'l':<br /> ap_show_modules();<br /> destroy_and_exit_process(process, 0);<br /><br /> case 'L':<br /> ap_show_directives();<br /> destroy_and_exit_process(process, 0);<br /><br /> case 't':<br /> configtestonly = 1;<br /> break;<br /><br /> case 'S':<br /> configtestonly = 1;<br /> new = (char **)apr_array_push(ap_server_config_defines);<br /> *new = "DUMP_VHOSTS";<br /> break;<br /><br /> case 'M':<br /> configtestonly = 1;<br /> new = (char **)apr_array_push(ap_server_config_defines);<br /> *new = "DUMP_MODULES";<br /> break;<br /><br /> case 'h':<br /> case '?':<br /> usage(process);<br /> }<br /> }<br /><br /> /* bad cmdline option? then we die */<br /> if (rv != APR_EOF || opt->ind < opt->argc) {<br /> usage(process);<br /> }<br /><br /> apr_pool_create(&plog, pglobal);<br /> apr_pool_tag(plog, "plog");<br /> apr_pool_create(&ptemp, pconf);<br /> apr_pool_tag(ptemp, "ptemp");<br /><br /> /* Note that we preflight the config file once<br /> * before reading it _again_ in the main loop.<br /> * This allows things, log files configuration<br /> * for example, to settle down.<br /> */<br /><br /> ap_server_root = def_server_root;<br /> if (temp_error_log) {<br /> ap_replace_stderr_log(process->pool, temp_error_log);<br /> }<br /> server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);<br /> if (!server_conf) {<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> if (ap_run_pre_config(pconf, plog, ptemp) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,<br /> NULL, "Pre-configuration failed");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> rv = ap_process_config_tree(server_conf, ap_conftree,<br /> process->pconf, ptemp);<br /> if (rv == OK) {<br /> ap_fixup_virtual_hosts(pconf, server_conf);<br /> ap_fini_vhost_config(pconf, server_conf);<br /> apr_hook_sort_all();<br /><br /> if (configtestonly) {<br /> ap_run_test_config(pconf, server_conf);<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");<br /> destroy_and_exit_process(process, 0);<br /> }<br /> }<br /><br /> signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server);<br /> if (signal_server) {<br /> int exit_status;<br /><br /> if (signal_server(&exit_status, pconf) != 0) {<br /> destroy_and_exit_process(process, exit_status);<br /> }<br /> }<br /><br /> /* If our config failed, deal with that here. */<br /> if (rv != OK) {<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> apr_pool_clear(plog);<br /><br /> if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,<br /> 0, NULL, "Unable to open logs");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,<br /> NULL, "Configuration Failed");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> apr_pool_destroy(ptemp);<br /><br /> for (;;) {<br /> apr_hook_deregister_all();<br /> apr_pool_clear(pconf);<br /><br /> for (mod = ap_prelinked_modules; *mod != NULL; mod++) {<br /> ap_register_hooks(*mod, pconf);<br /> }<br /><br /> /* This is a hack until we finish the code so that it only reads<br /> * the config file once and just operates on the tree already in<br /> * memory. rbb<br /> */<br /> ap_conftree = NULL;<br /> apr_pool_create(&ptemp, pconf);<br /> apr_pool_tag(ptemp, "ptemp");<br /> ap_server_root = def_server_root;<br /> server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);<br /> if (!server_conf) {<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> if (ap_run_pre_config(pconf, plog, ptemp) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,<br /> 0, NULL, "Pre-configuration failed");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> if (ap_process_config_tree(server_conf, ap_conftree, process->pconf,<br /> ptemp) != OK) {<br /> destroy_and_exit_process(process, 1);<br /> }<br /> ap_fixup_virtual_hosts(pconf, server_conf);<br /> ap_fini_vhost_config(pconf, server_conf);<br /> apr_hook_sort_all();<br /> apr_pool_clear(plog);<br /> if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,<br /> 0, NULL, "Unable to open logs");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {<br /> ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,<br /> 0, NULL, "Configuration Failed");<br /> destroy_and_exit_process(process, 1);<br /> }<br /><br /> apr_pool_destroy(ptemp);<br /> apr_pool_lock(pconf, 1);<br /><br /> ap_run_optional_fn_retrieve();<br /><br /> if (ap_mpm_run(pconf, plog, server_conf))<br /> break;<br /><br /> apr_pool_lock(pconf, 0);<br /> }<br /><br /> apr_pool_lock(pconf, 0);<br /> destroy_and_exit_process(process, 0);<br /><br /> return 0; /* Termination 'ok' */<br />}<br /><br /></pre><br /></div></div></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-14328125637979164022009-04-21T23:33:00.005+08:002009-07-06T17:25:45.765+08:00Multithreading in Windows Forms當你寫一個Windows Forms的Application時候,如果再用上Thread的功能,這時候可能就會發生:<span style="font-weight:bold;">跨執行緒作業無效: 存取控制項 'controls_name' 時所使用的執行緒與建立控制項的執行緒不同。</span>哇!我也是第一次遇到,程式寫的少了...還好有解,並得到建德兄的幫助來解決。<div><br /></div><div>可以參考MSDN:<a href="http://msdn.microsoft.com/zh-tw/library/ms229730.aspx">http://msdn.microsoft.com/zh-tw/library/ms229730.aspx</a></div><div><br /></div><div>尤其是這篇:<a href="http://msdn.microsoft.com/zh-tw/library/ms171728.aspx">進行對 Windows Form 控制項的安全執行緒呼叫</a></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-3030017435563320772009-04-19T00:50:00.019+08:002009-04-25T02:31:49.568+08:00TPC-W基準<span class="blsp-spelling-error" id="SPELLING_ERROR_0">TPC</span>-W是<span class="blsp-spelling-error" id="SPELLING_ERROR_1">TPC</span>所制定的一個<span class="Apple-style-span" style="font-weight: bold;">基準(benchmark)</span>,主要是用在交易型網路電子商務(transactional web e-Commerce)上面,目的為測試系統的效能並給予量化(給出數據)。<div><br /></div><div><span class="blsp-spelling-error" id="SPELLING_ERROR_2">TPC</span>-W所測量出來的數據單位為<span class="blsp-spelling-error" id="SPELLING_ERROR_3"><span class="Apple-style-span" style="font-weight: bold;">WIPS</span></span><span class="Apple-style-span" style="font-weight: bold;">(Web Interaction Per Second)</span>,以表示效能(performance)的程度,這就是throughput的多寡。2.0版本之後,是用SIPS(Service Interaction Per Second)的單位,不過,目前的資料多以WIPS為單位就是了,可能是2.0版本還未實際應用。</div><div><br /></div><div>除了WIPS之外,也有將總體成本除以throughput的方式,用以評斷設備是不是划算(即Cost/Performance, CP值)!其單位為$/WIPS。</div><div><br /></div><div>TPC-W的量測以一個應用伺服器(application server)為主,避免cluster的問題使得benchmark的數據有所差異。也就是說在TPC-W個規範當中,你是不能用來測量cluster的架構!</div><div><br /></div><div>TPC-W中有些專有名詞,其定義如下:</div><div><ul><li><span class="Apple-style-span" style="font-weight: bold;">Emulated Browser (EB)</span>, Emulated Business (EB)<br />模擬的瀏覽器,功能是向SUT發送工作量(workload)。2.0版的文件改用Emulated Business 表示。</li><li><span class="Apple-style-span" style="font-weight: bold;">Remote Browser Emulator (RBE)</span>, Remote Business Emulator (RBE)<br />這是用來管理和控制EB的軟體。</li><li>Business Session Length (BSL)<br />交易的數量,也就是REB和SUT之間的交易數量。</li><li><span class="Apple-style-span" style="font-weight: bold;">System Under Test (SUT)</span><br />欲測試的系統,可能包含多個server和router。</li><li>Payment Gateway Emulator (PGE)<br />模擬SUT外面的付費授權機制的服務,提供帳務處理功能。</li></ul><div>目前網路上已有實作的程式碼,有需要研究的人可以參考,分別如下:</div><div><ul><li>威斯康辛大學(最初發展版本)<br /><a href="http://www.ece.wisc.edu/~pharm/">http://www.ece.wisc.edu/~pharm/</a></li><li>紐約大學(改進版,使用J2EE)<br /><a href="http://www.cs.nyu.edu/totok/">http://www.cs.nyu.edu/totok/</a><br /></li><li>維吉尼亞大學(上兩個的綜合版,使用J2EE)<br /><a href="http://www.cs.virginia.edu/~th8k/">http://www.cs.virginia.edu/~th8k/</a><br /></li></ul><div>根據我最近的研究,2.0版本似乎不夠完全,1.8版的benchmark比較正常一點!而且實做的程式目前只到1.8版。另外,2.0個好像跟1.x完全不一樣。<br /></div></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-74647244267079057862009-04-13T14:07:00.011+08:002009-04-14T00:58:37.345+08:00Benchmark今天談談<span style="font-weight: bold;">Benchmark</span>,Benchmark的中文是<span style="font-weight: bold;">基準</span>,也有人說是<span style="font-weight: bold;">標竿測試</span>(應該用benchmark test)、<span style="font-weight: bold;">測試基準</span>,中文的意思實在很難照字面解釋。Benchmark的意思是:一些基本的方法來量測<span style="font-weight: bold;">系統的效能</span>(這是一個活動,所以英文用<span style="font-weight: bold;">benchmarking</span>)。而Benchmark通常指的是測試用的軟體工具。<br /><br />在量測系統效能當中,有兩項數據重要:<span style="font-weight: bold;">時間(time)</span>、<span style="font-weight: bold;">比率(rate)</span>。時間指的是反應時間(response time);比率指的是工作處理量,通常是單位時間的交易量、單位時間的回應次數,或者說是throughput。其實一個是從使用者的角度來觀看,另一個是從管理者的角度來觀看。<br /><br />比率的量測中以MIPS為單位,什麼是MIPS?MIPS即Millions of instructions per second,每秒條百萬指令,通常是用來測試CPU(而CPU不太會用頻率Hz為基準比較)。要注意的是MIPS也不一定準確,因為CPU有區分<span class="blsp-spelling-error" id="SPELLING_ERROR_0"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">RISC</span></span>和<span class="blsp-spelling-error" id="SPELLING_ERROR_1"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">CISC</span></span>兩種,所以用一件工作來比較,有可能產生不同效能結果。<br /><br /><span style="font-weight: bold;">系統效能(System Performance)</span>是一件很複雜的事情,因為系統包含多個軟體與硬體,要量測更是困難(使用benchmark),就算我們得到其結果,要解釋其效能結果更不是一件容易的事情。<br /><br />Benchmark從量測的性質來看,可以分為兩大類:粗糙基準(coarse-grain benchmark),細微基準(fine-grain benchmark)。另外,以系統角度來看可以分為四個階層(<span style="font-weight: bold;">hierarchy</span>),由內而外分別是。<br /><ol><li>Basic Operations(最內層)<br />加減法運算,測量CPU之類。對系統效能量測實用性低。<br /></li><li>Toy Benchmark<br />用一些難解的問題(puzzle)計算。<br /></li><li>Kernels<br />主要是一些程式的片段,或者函數之類。測量系統某部分的效能。<br /></li><li>Real Programs(最外層)<br />最趨於真實程式的測量,也是對系統的效能量測實用性最高的。(有點廢話...)</li></ol>要注意的是,每一種benchmark有不同的<span style="font-weight: bold;">運用場合(domain-oriented)</span>,好比你不能拿測量CPU的軟體去測量網路頻寬,可能不能測量,就算可以,其結果也沒有什麼意義!(有點誇張的例子,但要注意且記得!)<br /><br />常用的benchmark有下列單位制訂:(中文看看就好,沒有官方的中文名字,而且翻譯也怪怪的)<br /><ul><li>Transaction Processing Performance Council (交易處理效能機構),簡稱<span class="blsp-spelling-error" id="SPELLING_ERROR_2"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">TPC</span></span>。<br />有TPC-C, TPC-H, TPC-R, TPC-W </li><li>Standard Performance Evaluation Corporation(標準性能評估機構),簡稱SPEC。<br />有SPECxxxx, SPECweb</li></ul>效能測試(Performance Test)的類型基本上有3種:<br /><ul><li>Load Testing(負載測試)<br />模擬實際的使用情形,取得測試結果,看看是不是符合要求。<br /></li><li>Stress Testing(壓力測試)<br />在最糟的情況下,對服務施加最大負載量。看看是不是能正常運作。<br /></li><li>Spike Testing(突波測試)<br />施加比平均負載高出好幾倍的量,通常施加的時間為一段小週期。</li></ul>以上簡短介紹Benchmark和Performance Test。Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-1295518929424881382009-04-13T00:45:00.012+08:002009-09-09T00:29:32.270+08:00HttpWebRequest and HttpWebResponse之前有介紹.NET Framework的<span style="font-weight: bold;">WebClient</span>這個類別,用了用了發現我還需要更多功能,只好往下一層類別來找答案。WebClient用起來真的很容易,程式沒有幾行就可以做到一個功能,所以學習的時候,建議先用這個類別來玩玩看,先從簡單的開始,這是解決問題的第一步。<br /><br />HttpWebRequest和HttpWebResponse兩個類別,是從另外兩個抽象類別繼承而來,各分別<span style="font-weight: bold;">WebRequest</span>和<span style="font-weight: bold;">WebResponse</span>兩個,你待會看程式的時候,就會發現比起WebClient要多幾個步驟才能做一件事。<br /><br />在開始使用HttpWebRequest和HttpWebResponse之前,我們先來看看<span style="font-weight: bold;">HTTP(Hypertext Transfer Protocol)</span>這個通訊協定,似乎HTTP隨著WWW的發展越來越顯得重要,太多地方都用了!HTTP所傳送的message有兩種格式,一個是request message,另一個是response message。(這不是廢話,client-server的架構大概都是這樣。下面列出message的大概格式,主要是給個view,要詳細的資料請google)<br /><br /><span style="font-size:180%;">Request Message</span><br /><ul><li>Request Line<br />method+sp+URL+sp+Version+cr+lf<br /></li><li>Header Lines<br />header field name:+sp+value+cr+lf<br />header field name:+sp+value+cr+lf<br />...<br /></li><li>Blank Line<br />cr+lf<br /></li><li>Entity Body<br />要求的上傳資料<br /></li></ul><span style="font-size:180%;">Response Message</span><br /><ul><li>Status Line<br />version+sp+status code+sp+phrase+cr+lf<br /></li><li>Header Lines<br />header field name:+sp+value+cr+lf<br />header field name:+sp+value+cr+lf<br />...<br /></li><li>Blank Line<br />cr+lf<br /></li><li>Entity Body<br />回傳的資料(網頁內容)<br /></li></ul>說明一下上面兩個message的意思,因為畫表格說明不太容易,只好用條列式的方式展現。注意:所有的<span style="font-weight: bold;">HTTP message都是用ASCII文字</span>。(+號是為了區分欄位,實際上的message沒有出現)<br /><ul><li>cr= carriage return(回到最前面)</li><li>lf=line feed(換行)</li><li>sp=space(空白)</li></ul><div>接下來看看程式,用同步(Synchronous)的方式:</div><div><br /><pre class="brush:csharp"><br />//取得URI識別<br />Uri thisUri = new Uri(requestTextBox.Text);<br /><br />HttpWebRequest thisHttpWebRequest = (HttpWebRequest)WebRequest.Create(thisUri);<br /><br />//設定快取原則<br />HttpRequestCachePolicy thisHttpRequestCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);<br />thisHttpWebRequest.CachePolicy = thisHttpRequestCachePolicy;<br /><br />//提出同步要求,並且傳回包含回應的HttpWebResponse物件<br />HttpWebResponse thisHttpWebResponse = (HttpWebResponse)thisHttpWebRequest.GetResponse();<br /><br />//取得回應的header相關資料<br />messageTextBox.Text += thisHttpWebResponse.IsFromCache.ToString() + Environment.NewLine;<br />messageTextBox.Text += thisHttpWebResponse.StatusCode.ToString() + Environment.NewLine;<br /><br />//將多行的TextBox移到最後一列<br />messageTextBox.Select(messageTextBox.Text.Length, 0);<br />messageTextBox.ScrollToCaret();//將控制項的內容捲動到目前插入號的位置<br /><br />//關閉資料流,並釋放連線以重複使用<br />thisHttpWebResponse.Close();<br /></pre><br /></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-74426580529706414672009-04-11T01:50:00.007+08:002009-04-11T03:21:24.215+08:00System Properties系統特性系統特性(System Properties)當中有下列幾項定義,這邊介紹主要是用在效能評估上面,因為排隊理論通常就是用來解決這樣的問題,我們先定義,之後才有辦法討論。(這是參考<a href="http://as.wiley.com/WileyCDA/WileyTitle/productCd-0471565253.html">Queueing Networks and Markov Chains: Modeling and Performance Evaluation with Computer Science Applications, 2<span class="blsp-spelling-error" id="SPELLING_ERROR_0">nd</span> Edition</a>)<br /><br /><br /><ul><li><span style="font-weight: bold;">Performance</span>:(效能)<br />The degree to which a system or component accomplishes its designated functions within given constraints, such as speed, accuracy, or memory usage.</li><li><span style="font-weight: bold;">Reliability</span>:(可靠性)<br />The probability that the software will not cause the failure of the system for a specified time under specified condition.</li><li><span style="font-weight: bold;">Availability</span>:(可利用性)<br />The ability of a system to perform its required function at a stated instant or over a stated period of time.<br /></li><li><span style="font-weight: bold;">Dependability</span>:(可依賴性)<br />The dependability of a computer system is the ability to deliver a service that can justifiably be trusted.</li><li><span style="font-weight: bold;">Performability</span>:(可執行性)<br />The probability that the system reaches an accomplishment level y over a utilization interval (0,t).</li></ul>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-9372779275106270482009-04-10T14:11:00.015+08:002009-04-11T01:49:05.007+08:00Computer Simulation電腦模擬在工程和科學的領域當中,除了實際測量或是試驗之外,我們還可以模擬自然或人為(man-made)的現象。其中所模擬的對象是<span style="font-weight: bold;">系統(system)</span>,什麼是系統呢?一個系統可以視為元件的集合,組織這些元件使得它們可以完成一件目的。好比說一台電腦就是一個系統,包含無數個元件(CPU、記憶體、硬碟、主機板、鍵盤...),這些元件可以完成你要的一個目的,比方說上網、玩遊戲、看電影...。<br /><br />所謂的<span style="font-weight: bold;">模擬(simulation)</span>是根據以往經驗(<span style="font-weight: bold;">empirically</span>)來決定系統特性(characteristics)的一個實驗,主要方式為產生(generation)與觀察(observation)系統的資料,於是就能夠知道系統的一些結論(inference)。<br /><br />為何說是根據經驗呢?因為人類所知有限,根據人類的觀察和所推討的理論,盡可能來推測真實的發生情形。例如我們都知道東西會往下掉,推導出萬有引力的理論,那是不是全宇宙都是符合這個定律?我們不曉得,根據以往經驗來看是這樣的(東西會往下掉)。同樣的道理,模擬也是基於這樣的觀念,模擬必須有個<span style="font-weight: bold;">模型(model)</span>,而此模型則是基於經驗與理論的基礎,並且要盡可能<span style="font-weight: bold;">模仿(mimic)</span>或<span style="font-weight: bold;">仿真(emulate)</span>系統的行為。<br /><br />一個模型中的狀態以<span style="font-weight: bold;">狀態變數(state variable)</span>來表示,電腦上則是程式的變數(variable),一個模擬軟體事實上就是改變這些狀態變數,最後來觀測這些變數的數值,那要怎麼改變呢?則依照系統的模型(數學關係)。<br /><br />模擬所需的模型有下列幾種分類方法:<br /><ol><li>Continuous/Discrete</li><li>Deterministic/Stochastic</li><li>Terminating/Steady-State</li><li>Synthetic(Distribution-Driven)/Trace-Driven</li><li>Sequential/Distributed</li><li>Symbolic</li><li>Event-Oriented/Process-Oriented</li></ol>回到基本問題(模擬哲學),如果我們已經建立模型,而且證實這個模型式可用的、可靠的,我們要如何求解這個模型呢?方法有兩種,一個是模擬解(<span class="blsp-spelling-error" id="SPELLING_ERROR_0">Simulative</span> Solution),另一個是分析解(Analytic Solution),到底該用哪一種方法呢?Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-76532601825230323642009-04-09T13:51:00.012+08:002009-09-09T00:41:54.719+08:00WebClient ClassMSDN<br />英:<a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx">http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx</a><br />中:<a href="http://msdn.microsoft.com/zh-tw/library/system.net.webclient.aspx">http://msdn.microsoft.com/zh-tw/library/system.net.webclient.aspx<br /></a><br />先做個簡單的程式來學學網路應用程式,System.Net內的類別當中,我先用最高層次的類別來玩玩看,這個類別是WebClient,只能讓你當作client來使用。<br /><br />控制項<br /><ul><li>requestTextBox=輸入的網址</li><li>messageTextBox=訊息輸出</li></ul>程式<br /><br /><pre class="brush:csharp"><br /> try<br /> {<br /> //取得URI識別<br /> Uri thisUri = new Uri(requestTextBox.Text);<br /><br /> WebClient thisWebClient = new WebClient();<br /> //設定快取原則<br /> thisWebClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);<br /> //設定用於上載和下載字串的Encoding<br /> thisWebClient.Encoding = Encoding.UTF8;<br /><br /> //下載回應的body資料為string,呼叫DownloadString這會開始執行下載動作<br /> String thisDownloadString = thisWebClient.DownloadString(thisUri);<br /><br /> //取得回應的header資料<br /> messageTextBox.Text += thisWebClient.ResponseHeaders.ToString() + Environment.NewLine;<br /> messageTextBox.Text += thisDownloadString + Environment.NewLine;<br /><br /> //將多行的TextBox移到最後一列<br /> messageTextBox.Select(messageTextBox.Text.Length, 0);<br /> messageTextBox.ScrollToCaret();//將控制項的內容捲動到目前插入號的位置<br /><br /> }<br /> catch (Exception ex)<br /> {<br /> MessageBox.Show(ex.ToString());<br /> }<br /> finally<br /> {<br /> //clean up<br /> }<br /></pre><br /><br /><div><br />上述是<span style="font-weight: bold;">同步(Synchronous)</span>的方式,程式需等待下載命令執行完之後,才能繼續run,你的成是有可能會當掉鎖住,解決方式就是使用<span style="font-weight: bold;">非同步(Asynchronous )</span>方式,非同步<span sdata="memberAuthoredSummary">方法不會封鎖呼叫執行緒</span>。<br /></div><br /><br /><pre class="brush:csharp"><br /> try<br /> {<br /> //取得URI識別<br /> Uri thisUri = new Uri(requestTextBox.Text);<br /><br /> WebClient thisWebClient = new WebClient();<br /> //設定快取原則<br /> thisWebClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);<br /> //設定用於上載和下載字串的Encoding<br /> thisWebClient.Encoding = Encoding.UTF8;<br /><br /> //委派處理WebClient的DownloadStringCompleted 事件的方法<br /> thisWebClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(thisWebClient_DownloadStringCompleted);<br /><br /> //呼叫DownloadString這會開始執行下載動作<br /> thisWebClient.DownloadStringAsync(thisUri);<br /><br /> }<br /> catch (Exception ex)<br /> {<br /> MessageBox.Show(ex.ToString());<br /> }<br /> finally<br /> {<br /> //clean up<br /> }<br /><br /> void thisWebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)<br /> {<br /> //throw new NotImplementedException();<br /> try<br /> {<br /> //取得回應的body資料<br /> String thisDownloadString = e.Result.ToString() + Environment.NewLine;<br /><br /> //取得回應的header資料<br /> messageTextBox.Text += ((WebClient)sender).ResponseHeaders.ToString() + Environment.NewLine;<br /> messageTextBox.Text += thisDownloadString + Environment.NewLine;<br /><br /> //將多行的TextBox移到最後一列<br /> messageTextBox.Select(messageTextBox.Text.Length, 0);<br /> messageTextBox.ScrollToCaret();//將控制項的內容捲動到目前插入號的位置<br /><br /> }<br /> catch (Exception ex)<br /> {<br /> MessageBox.Show(ex.ToString());<br /> }<br /> finally<br /> {<br /> //clean up<br /> }<br /> }<br /></pre>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-37217450066286176032009-04-06T20:35:00.019+08:002009-04-16T00:24:31.511+08:00Networking Programming網路程式設計本篇文章介紹使用.NET Framework來撰寫網路應用程式,參考書籍可以看「Visual C# 2008網路程式設計之道」(真的是一本參考書),基峯資訊出版,黃嘉輝著,訂價台幣550元整。如果不想買的話,<span style="font-weight: bold;">可以參考<span class="blsp-spelling-error" id="SPELLING_ERROR_0"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">MSDN</span></span>的網站</span>,書裡面的內容和<span class="blsp-spelling-error" id="SPELLING_ERROR_1"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">MSDN</span></span>是差不多的,可以省下一些錢。<br /><br /><table style="width: auto;"><tbody><tr><td><a href="http://picasaweb.google.com/lh/photo/JbPOZvDqFoP3vgNtxbCrQQ?authkey=Gv1sRgCNmhtYCEnOy04AE&feat=embedwebsite"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoodh7C1gJZooMbwg3h64eVcgePbeD1o0zGprM0TIPx8SvvZ2uP0038EEVgzeRB885p6C_K7AuIKgkqukmgZM0R4IX_lQGJ13XE1LUx5wNBe8RX0zEa8nFC0fuHru3kAeyUCkZAPQ11Nc/s400/Picture%2029.jpg" /></a></td></tr></tbody></table>黃嘉輝(2008),Visual C# 2008網路程式設計之道,台北:碁峰。<div><div><br />要寫網路程式的話,最主要利用兩個<span class="blsp-spelling-error" id="SPELLING_ERROR_2"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">namespace</span></span>的類別(class),一個是<a href="http://msdn.microsoft.com/zh-tw/library/system.net.aspx">System.Net</a>,另一個是<a href="http://msdn.microsoft.com/zh-tw/library/system.net.sockets.aspx">System.Net.Sockets</a>。<br /><br />其中,建德兄說網路程式的設計與撰寫,可以利用非同步程式設計模式,參考<a href="http://msdn.microsoft.com/zh-tw/library/ms228969.aspx">http://msdn.microsoft.com/zh-tw/library/ms228969.aspx</a>,這會是比較優秀的方法,避免視窗程式鎖住當機。<br /><br />首先介紹<span class="blsp-spelling-error" id="SPELLING_ERROR_3"><span class="blsp-spelling-error" id="SPELLING_ERROR_3">OSI</span></span>七層,貼在這裡當作參考(關鍵字);<br /><ul><li>Application</li><li>Presentation</li><li>Session</li><li>Transport</li><li>Network</li><li>Data Link</li><li>Physical</li></ul>而<span class="blsp-spelling-error" id="SPELLING_ERROR_4">TCP</span>/<span class="blsp-spelling-error" id="SPELLING_ERROR_5">IP</span>類的模型為五層:(多數英文教科書的分類)<br /><ul><li>Application Layer(HTTP, FTP, SMTP, <span class="blsp-spelling-error" id="SPELLING_ERROR_6">DNS</span>...)</li><li>Transport Layer(<span class="blsp-spelling-error" id="SPELLING_ERROR_7">TCP</span>, <span class="blsp-spelling-error" id="SPELLING_ERROR_8">UDP</span>)</li><li>Network Layer(<span class="blsp-spelling-error" id="SPELLING_ERROR_9">IP</span>)</li><li>Data Link Layer(Ethernet)</li><li>Physical Layer</li></ul>在.NET Framework中有許多類別可以使用,依照逞用程度和功能性來區分:(其中符號||左邊為client用,右邊為server用)<br /><ul><li>System.Net.WebClient||無</li><li>System.Net.WebRequest, System.Net.WebResponse||無</li><li>System.Net.TcpClient,System.Net.UdpClient||System.Net.TcpListner,System.Net.UdpListner</li><li>System.Net.<span style="font-weight: bold;">Sockets</span>(沒有區分client-server)</li></ul>依照容易使用(ease of use)的程度來看,最上面最簡單容易使用,而最下面System.Net.Sockets使用較複雜,相對的,因為System.Net.Sockets較複雜,原因是功能性(Functionality)最完善,你可以自己處理最多功能。到底要用哪一個類別來開發,依照需求來決定。<br /><br />以<span style="font-weight: bold;">WebClient</span>類別來說,WebClient使用下層的<span style="font-weight: bold;">WebRequest</span>和<span style="font-weight: bold;">WebResponse</span>製作,避免讓我們接觸下層的複雜功能,也因此限制了一些!所以使用上要注意,進階功能還是要使用下層的類別。另外,WebClient類別僅<span style="font-weight: bold;">支援HTTP、FTP、file</span>的通訊協定,這可能是因為WebRequest和WebResponse的繼承類別只有這三類,所以僅支援HTTP、FTP、file囉!<br /><br />如果要操作TCP和UDP的話,就使用System.Net.TcpClient ,System.Net.UdpClient, System.Net.TcpListner, System.Net.UdpListner這些類別。如果不要通訊協定的話,那就用最底層的System.Net.Sockets類別,Sockets類別跟任何通訊協定沒有關係。<br /><br />另外,由於抽象類別<span style="font-weight: bold;">WebRequest</span>和<span style="font-weight: bold;">WebResponse</span>有其他類別繼承,所謂的<span style="font-weight: bold;">抽象類別(Abstract Class)</span>是僅可以讓其他類別繼承(inherit),不能產生實體,你不能直接拿WebRequest和WebResponse來用,記住抽象類別這個特性。其關係為:<br /><br />System.Net.WebRequest的子類別:<br /><ul><li>HttpWebRequest</li><li> FtpWebRequest</li><li> FileWebRequest</li></ul><br />System.Net.WebResponse的子類別:<br /><ul><li>HttpWebResponse</li><li> FtpWebResponse</li><li> FileWebResponse</li></ul></div></div>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-13797792354015133432009-04-01T15:20:00.004+08:002009-04-09T13:49:56.239+08:00Key word對於要學習Queueing Theory的人來說,可以建議用下列關鍵字來搜尋。<br /><ul><li>queueing system</li><li>performance evaluation</li><li>stochastic model</li></ul>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-29846128738087649692009-03-31T15:43:00.011+08:002009-04-01T16:02:00.332+08:00Research of Queueing Theory這篇主要是想寫「誰在研究排隊理論?」,我有詢問過<span class="blsp-spelling-error" id="SPELLING_ERROR_0">ycwang</span>老師,他是說有幾個地方,記得沒錯的話,會在下面列出來。為什麼要知道呢?其實做任何事都會有個憧憬,總是想去某個地方看看,而這個地方具有其重要性、指標性的意義。<br /><br />比方說想到浪漫,就會想去歐洲看看;想到設計,就會想到北歐看看;想到美國,就想去紐約看看...等等。有點類似朝聖的味道,排隊理論也是如此,總想去那個研究特別發達的學校或是單位看看,看他們在做些什麼。<br /><br />全世界研究Queueing Theory可以分為兩類,一個是理論(Theory) ,另一個是應用(Application),美國偏向應用,歐洲偏向理論,大致上是這樣。台灣呢?是偏向"代工"嗎...。<br /><br />有個國外網站專門蒐集排隊理論的資訊,請參考<a href="http://web2.uwindsor.ca/math/hlynka/queue.html">http://web2.uwindsor.ca/math/hlynka/queue.html</a><br /><br />以下為有研究Queueing Theory的知名單位:(陸續補充)<br /><br /><span style="font-weight: bold;">台灣(Taiwan)</span><br />National Tsing Hua University<br />國立清華大學<a href="http://www.nthu.edu.tw/">http://www.nthu.edu.tw/</a><br /><br /><br /><span style="font-weight: bold;">美國(United States of America, USA)</span><br />University of Illinois at Urbana-Champaign<br />伊利諾大學香檳分校,<a href="http://illinois.edu/">http://illinois.edu/</a><br /><br /><span style="font-weight: bold;">法國(France)</span><br />the French national institute for research in computer science and control<br />法國國家電腦科學與控制研究院,簡稱INRIA<br /><a href="http://www.inria.fr/index.en.html">http://www.inria.fr/index.en.html</a><br /><br /><span style="font-weight: bold;">荷蘭(Netherlands)</span><br /><br /><br /><span style="font-weight: bold;">德國(Germany)</span>Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0tag:blogger.com,1999:blog-408860534301094607.post-91118306434489560872009-03-31T15:15:00.009+08:002009-03-31T15:38:21.371+08:00SimEvents Library先將SimEvents中的Library整理成清單,之後會用到,依照字母排列,也剛好是Simulink的排列方式:<br /><ul><li>Attributes<br /> <ul><li>Get Attribute</li> <li>Set Attribute<br /></li></ul></li><li>Entity Management<br /> <ul><li>Entity Combiner<br /> </li><li>Entity Splitter<br /></li></ul></li><li>Event Translation<br /> <ul><li>Entity Departure Event to Function-Call Event<br /> </li><li>Signal-Based Event to Function-Call Event<br /></li></ul></li><li>Gates<br /> <ul><li>Enabled Gate<br /> </li><li>Release Gate<br /></li></ul></li><li>Generators<br /> <ul><li>Entity Generators<br /> <ul><li>Event-Based Entity Generator<br /> </li><li>Time-Based Entity Generator<br /> </li></ul></li><li>Event Generators<br /> <ul><li>Entity-Based Function-Call Event Generator<br /> </li><li>Signal-Based Function-Call Event Generator<br /> </li></ul></li><li>Signal Generators<br /> <ul><li>Event-Based Random Number<br /> </li><li>Event-Based Sequence<br /></li></ul></li></ul></li><li>Probes<br /> <ul><li>Entity Departure Counter<br /></li></ul></li><li>Queues<br /> <ul><li>FIFO Queue<br /> </li><li>LIFO Queue<br /> </li><li>Priority Queue<br /></li></ul></li><li>Routing<br /> <ul><li>Input Switch<br /> </li><li>Output Switch<br /> </li><li>Path Combiner<br /> </li><li>Replicate<br /></li></ul></li><li>Servers<br /> <ul><li>Infinite Server<br /> </li><li>N-Server<br /> </li><li>Single Server<br /></li></ul></li><li>Signal Management<br /> <ul><li>Initial Value<br /> </li><li>Singal Latch<br /></li></ul></li><li>SimEvents Ports and Subsystems<br /> <ul><li>Conn<br /> </li><li>Din<br /> </li><li>Discrete Event Subsystem<br /> </li><li>Dout<br /> </li><li>Subsystem Configuration<br /></li></ul></li><li>SimEvents Sinks<br /> <ul><li>Attribute Scope<br /> </li><li>Discrete Event Signal to Workspace<br /> </li><li>Entity Sink<br /> </li><li>Instantaneous Entity Counting Scope<br /> </li><li>Instantaneous Event Counting Scope</li><li>Signal Scope<br /> </li><li>X-Y Attribute Scope<br /> </li><li>X-Y Signal Scope<br /></li></ul></li><li>SimEvents User-Defined Functions<br /> <ul><li>Attribute Function<br /></li></ul></li><li>Timing<br /> <ul><li>Cancel Timeout<br /> </li><li>Read Timer<br /> </li><li>Schedule Timeout<br /> </li><li>Start Timer</li> </ul></li></ul>中文呢?有沒有統一的中文翻譯,似乎沒有。那就自己翻譯吧!Zheng-Yuan Wuhttp://www.blogger.com/profile/11445480880895206040noreply@blogger.com0