2015年12月3日 星期四

Win 8.1 安裝 IIS 伺服器

今天收到資安單位來函要求將 IE 升版到 IE11, 以避免安全漏洞. 這給我出了個難題, 因為我的新版工作日誌系統還沒弄好, 而目前使用的舊系統只能在 IE9 以下跑, 升到 IE10 就會有問題 (編輯器 & 檔案上傳). 為今之計只有將舊系統改版應急才是上策. 舊系統使用 IIS+ASP+ACCESS 設計, 而我的電腦已經沒有一台有 IIS 伺服器, 只好上網搜尋安裝 IIS 的方法, 參考 :

# 如何在 Windows 8 安裝 IIS 8 ?
# 在 IIS 上建置傳統 ASP 網站

我的筆電是 WIN8.1, 所以就按圖索驥試試看, 安裝紀錄如下 :

首先按 Windows+Q 鍵, 在搜尋框內輸入 feature :


點選 "開啟或關閉 Windows 功能" :
勾選 Internet Information Service 以及 Web 管理工具下的項目如下 :


同時也選應用程式項下的 ASP 與 ISAPI 擴充程式 :


按確定就開始搜尋必要的檔案, 完成後就可以到 "控制台/系統管理工具", 點選 "Internet Information Services (IIS) 管理員", 點選左方 "連結" 面板中的 "站台", 可看到其預設網站繫結 :


由於我的筆電早已安裝 Apache+PHP+mySQL, HTTP 80 埠已經被 Apache 伺服器用了, 為了避免衝突, 必須將 IIS 的改為其他埠號, 例如 81. 在預設站台列上按滑鼠右鍵, 點選 "繫結" :


按編輯, 將 PORT 改為 81, 主機名稱設為 localhost :


然後點選 Default Web Site, 按滑鼠右鍵, 點選 "管理網站/啟動" 來啟動網站 :


這樣就完成 localhost 網站設定了, 打開瀏覽器連線 localhost:81 即可 :


這是 ASP 的預設站台, 如果要建立自己的網站, 先點選 "站台", 按滑鼠右鍵, 點選 "新增網站" :


在彈出選單中設定網站屬性 :


此處我將網站檔案放在 E:\myasp 下, 而且網站取名 myasp, 所以實體路徑只要填 E:\ 即可 (不要填 E:\myasp, 這樣 IIS 會以為是 E:\myasp\myasp), 我以為這樣就 OK 了, 就啟動 myasp 站台, 然後用瀏覽器連線 localhost:81/myasp 卻得到如下錯誤訊息 :

An error occurred on the server when processing the URL. Please contact the system administrator.
If you are the system administrator please click here to find out more about this error.


我在 "在IIS7中顯示ASP偵錯訊息" 這篇找到解法, 原來 IIS8 預設是關閉 ASP 的偵錯訊息的, 先點選 myasp 站台, 再點 ASP 按鈕 :


在選單的 "編譯/偵錯內容" 的 "將錯誤傳送到瀏覽器" 從 False 改為 True (同時也將伺服端與用戶端偵錯打開), 然後按右上角 "動作/套用" 即可 :


這時將 localhost:81/myasp 重新整理就會顯示錯誤訊息了 :

ADODB.Connection 錯誤 '800a0e7a'

找不到提供者。它可能未被正確安裝。

/myasp/sys_bin\access_adodb_connection_sys.asp, 行10


看起來是跟資料庫連線有關, 因為我的 myasp 架站系統採用 ACCESS 資料庫, 需使用 Microsoft.Jet.OLEDB.4.0 這個 32 位元程式來建立連線, 而 IIS 預設不執行 32 位元程式, 參考 :

# ADODB.Connection 錯誤 '800a0e7a'

點選站台按滑鼠右鍵, 再點進階設定 :


將 "一般/啟用 32 位元應用程式" 改為 True 即可 :


如此這般, 再重新整理 localhost:81/myasp 就能看到 myasp 網站的畫面了 :


這個  12 年前開發的老骨董是我模仿當時很紅的 myPHPnuke 架站機用 JScript 寫的 ASP 版本, 我只是把 myPHPnuke 架好, 然後將主要的功能大略玩一遍, 了解其運作模式後就開工了, 也沒有去研究它是怎麼寫的 (還沒學 PHP, 看不懂). 那時最主要的目的是為了寫碩士論文, 因為蒐集了一堆文獻, 研讀之後需要做筆記, 為了在寫文獻回顧時搜尋方便, 就花了一個多月寫了這個 ASP 架站機, 畢業後就拿到公司用, 沒想到一用就超過十年了.

ASP 已經是很舊的技術了, 但因我對 .NET 一直無法認同, 所以也不想進階到 ASP.NET. 就算是 ASP 我也是用 Javascript 寫, 絕不用 VBScript.

其他參考 :

# http://demos.telerik.com/kendo-ui/editor/index (HTML 編輯器)
# 網站無法執行 - 程序無法存取檔案

2015-12-04 補充 :

今天又發現一個 IIS 設定的問題, 因為 sys_bin 下的 include_programs_iis.asp 這個程式在含括應用程式檔案時會用到上層目錄 :

  case 'jlog' : {
%>       <!-- #include file="..\bin\jlog.asp" --><%
     break;}

所以進入應用程式時會出現下列錯誤 :

Active Server Pages 錯誤 'ASP 0131'
不允許的上層路徑
/myasp/sys_bin\include_programs_iis.asp, 行63
包含檔案 '..\bin\jlog.asp' 不能包含 '..' 來指出上層目錄。


這要在 ASP 中開啟上層目錄 :


注意, 在 "編譯/指令碼語言" 欄位我已將預設的 VBScript 改成 JScript, 因為我的 ASP 專案全部都是用 Javascript 寫的.

2015-12-08 (二) 補充 :

今天測試工作日誌的上傳功能時發現, IIS 8 跟以前 XP 時代的 IIS 6 不同之處是其 ASP 指令碼解譯欄位似乎只能在預設的 VBScript 與 JScript 中選一個填, 以前可以填兩個, 但現在不管填 JScript;VBScript 或 JScript, VBScript 都無法執行. 我的工作日誌全部用 JScript 寫, 唯獨檔案上傳處理程式使用了 VBScript, 這是從所買的 ASP 書裡面抄來的. 最後在下面這篇找到解法 :

# Call a function written on VB from a JScript code (classic ASP)

原來只要在上傳處理程式 fupaction.asp 開頭加上下面這行即可 :

<%@ Language="VBScript" %>

此指令是強制伺服器改用 VBScript 解譯器來執行程式中的命令.



2015年12月1日 星期二

線上 C 編譯器 TutorialsPoint

今天在網路上找到 TutorialsPoint 的線上 C 程式編譯器, 如果電腦有連上網路, 不需要安裝 C 編譯器也可以線上撰寫, 編譯, 與執行 C 程式 :

# TutorialsPoint : CodingGround : Compile and Execute C Online

操作介面很簡潔, 左上方是檔案總管, 按 "+" 可以新增檔案; 點選檔案再按滑鼠右鍵可操控檔案 (更名, 刪除, 下載 ...). 右方是程式編輯區, 預設開啟 Hello World 的 C 程式範本, 寫好後先按 "Compile" 編譯, 再按 "Execute" 即執行.


下方是終端機回應, 執行的結果會顯示在此. 右上角有許多功能選單, 例如可以上傳在本機寫好的程式, 也可以將整個專案打包下載為 tar.gz 壓縮檔.


其實 TutorialsPoint 不只能線上編譯執行 C 程式, 幾乎提供了大部分主流程式語言 (Java, Python, C#, C++, ...) 的線上執行功能 :

# http://www.tutorialspoint.com/codingground.htm

此線上工具也提供了語法速查, 例如 C 語言的在此 :

# http://www.tutorialspoint.com/cprogramming/index.htm

有這麼好用的工具, 只要有網路就不需要安裝 C 編譯器啦! 尤其是此網站不需要註冊登入啊甚麼的, 連上網站馬上就能編寫驗證程式.


2015年11月30日 星期一

第 48 周記事

本周因為菁周日補習班要魔訓, 姊姊要去畫室補課, 只有我回鄉下. 舅媽說過幾年等她們都出去上大學, 到時就真的只有我一個人回鄉下矣. 現在要開始為離巢期作心理準備.

週六早上載姊姊去樹德考英檢中級複試, 記得國二考初級也是在這裡. 中午兩個人附近陶林吃刷刷鍋, 算是難得的小確幸啦! 單點的就吃得好飽, 可見吃到飽餐廳是多麼不健康.

週六傍晚回到家, 爸說小舅跟婷婷他們才剛回去, 他們已經幫我採收第一期玉米, 留下五支給我, 哇咧, 晚一步竟慘遭劫掠! 哈, 開玩笑的啦! 早一點回來結果也是差不多, 我種這些也是想要延續母親的慷慨, 有東西可以餽贈親友. 以前親友來訪, 媽總是有辦法從菜園弄出些東西讓他們帶回去. 晚上吃過飯趕緊將鮮採玉米下鍋, 必須在採摘後兩小時內煮, 這樣才能保住玉米的甜味, 我連煮玉米都用過濾水, 帶鬚帶殼煮過後當茶喝非常甜美.

週日去市集順便去種子行再買 10 棵甜玉米來種, 老闆沒聽清楚, 以為要買三十棵, 等到搞清楚才說 : 蛤? 我趕快解釋, 我是每一兩周種十棵, 這樣到過年時每周都有玉米收成, 不是很好嗎? 一下子收成太多很麻煩, 因為要分送親友時間太趕來不及, 玉米就是要鮮採下鍋才好吃.

晚飯後想起曾國藩說的 "飯後百步走, 活到九十九", 就在曬穀場走了二十分鐘, 算了一下, 繞一圈大概 70 步. 不過, 飯後散步不可快步, 必須悠閒慢走, 否則傷胃也.



紅頭髮的安妮

今天打開 Google 首頁, 發現每日圖檔是紀念加拿大作家-清秀佳人 (Anne of The Green Gables) 的作者露西·莫德·蒙哥馬利 (Lucy Maud Montgomery) 141 歲誕辰 :



我是在 1990~1991 年左右在電視上看到 "清秀佳人 (Anne of The Green Gables)" 這部迷你影集, 當時我在電腦公司做 IC 設計, 每天都要加班到 10 點以後 (最晚是到早上五點). 但為了看這部片 (精確一點, 是為了看梅根法蘿), 那幾周都提早在九點前回去隔壁棟的宿舍, 這是繁忙的研發工作生涯中的一段小確幸.

我不但迷梅根法蘿, 還買了整套清秀佳人原文小說 (好像有三, 四本). 有一段時間行囊中就是這本書, 一有空就看. 但是看到第二本就後繼乏力了, 因為我看的電視劇集內容取材於第一本 (Anne of The Green Gables),  後面的沒看所以就興趣缺缺了. 不過一次偶然機會裡讓我買到了原版 DVD, 偶而拿來看看, 回味一下當年在公司宿舍大客廳大家一起看的記憶.

電視劇是在露西的家鄉愛德華王子島拍攝的, 播出後曾掀起一陣觀光熱潮. 愛德華王子島位於加拿大東岸, 原為法國殖民地, 在英法七年戰爭後割讓給英國並改名, 以紀念英王喬治三世的第四子愛德華王子 (即維多利亞女王的爸爸). 愛德華王子島也是加拿大建國時各英屬殖民地代表第一次會議的地點, 但後來卻因為對條款不滿而未加入加拿大, 直到因建鐵路債台高築才加盟, 成為加拿大第七個省, 參考 :

# 愛德華王子島


露西在 1942 年死於血栓, 但據其孫女後來透露, 露西其實是死於自殺, 因為在長期照顧罹患憂鬱症的丈夫, 以及生活中的種種不順 (長子品行不好, 次子可能要上前線, 為了清秀佳人這本書而跟出版社打官司), 自己也得了憂鬱症而服食安眠藥過量死亡.

理想與現實之間總是有一個很大的鴻溝, 當文學世界中的美好映射到現實世界的不完美時, 總是讓人悵然若失. 但有幾個人會覺得生命是完美的呢? 文學的價值, 或許就是要填補這種不完美吧!


2015年11月25日 星期三

兩本 C 語言好書與 Dev C++ 安裝

最近因為測試 ARDUINO+ESP8266 伺服器程式遇到許多問題, 突然覺得得好好搞懂 C 語言的陣列, 字串, 以及指標這三個常用的技巧. 上週六第二次去市圖總館借書, 就找到一本 C 語言的好書, 現在手邊共有三本 C 語言的書, 但我覺得以下這兩本寫得最好 :

# 碁峰, 李啟龍, 第一次學就上手-從 C 程式範例到專題製作 (第一版)
這本書今年出第二版了, 我看目錄與第一版完全一樣, 應該是賣得不錯吧! 碁峰出的書我覺得品質是數一數二的. 作者曾當選大學優良教師, 寫作風格言簡意賅不囉嗦, 例如第九章介紹字串與字元陣列, 用一張圖就清楚說明兩者的差別是, 字串就是以 \0 (NULL) 結尾的字元陣列, 寫作風格乾脆俐落.

此書附錄 B 介紹許多 C 語言的線上評測系統 (Online Judge), 可以作為參加程式設計競賽磨練程式技巧的工具 :

# ZeroJudge
# USACO
# UVA
# TIOJ
# PKUOJ
# VIJOS
# SPOJ
# URAL
# SGU

第二本好書是日本人氣作家高橋麻奈寫的 :

# 博碩, 高橋麻奈, 最新 C 語言程式設計實例入門 (第四版)


這本最棒的地方是作者會深入探討一些初學者容易搞混的觀念, 例如指標與陣列有何不同?  也詳細解說傳遞函式參數的各種方法, 特別是利用指標當引數, 解決傳值呼叫只能傳回一個值的問題. 此外書中以漫畫圖解程式的運作, 特別是資料在記憶體中的分布情形, 以利初學者能快速理解.

學習標準 ANSI C 語言需要一個編譯器, 我覺得以 Dev C++ 最適合初學者使用 (不知道為什麼, 我對微軟的 Visual XXX 就是有偏見), 目前為 5.11 版 :

# http://sourceforge.net/projects/orwelldevcpp/ (約 48MB)

安裝之前務必將之前的舊版 Dev C++ 移除, 再點 Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup.exe 安裝. 安裝語言選擇英文, 等第一次執行時再改為中文 :


按 "I Agree" 才能繼續執行 :


用預設的 Full (完整安裝) 即可 :


使用預設的安裝路徑 (也可以去掉中間的部分, 改安裝在 C:\Dev-Cpp) :



安裝完畢第一次啟動 Dev C++ 有選單可選擇使用之語言 :


使用預設值按下一步即可 :




點選 "檔案/開新檔案" 可以新增原始碼或專案, 如果只是寫個小程式, 選原始碼即可. 編寫的原始碼 (xxx.cpp) 與可執行檔 (xxx.exe) 預設是放在媒體櫃的文件下面, 這可以在 "環境選項/檔案目錄" 中更改 :


編輯器設定部分, 點選 "工具/編輯器選項", 勾選 "文字邊界範圍提示" 裡的 "啟用", 預設是 80 字元, 這樣會在編輯器第 80 行處顯示一條垂直線, 提醒我們一列敘述不要寫太長, 以免列印時反折到下一列. 另外我也把 "Tab 長度" 由預設的 4 改為 2, 因為我習慣每個階層縮兩格, 4 格太佔空間了.


這樣就可以開始編寫 C 程式了. C 程式的基本架構如下 :

#include <stdio.h>   //載入標準輸出入函式庫
#include <stdlib.h>  //載入標準系統函式庫

int main(void) {
  printf("Hello World!");   //輸出訊息至標準輸出 (螢幕)
  system("pause");  //停住執行視窗
  return 0;   //結束程式
  }

先按 Ctrl+F9 編譯程式, 若無編譯錯誤或警告再按 Ctrl+F10 即可執行, 或者直接按 F9 (編譯後執行) 亦可, 如果對程式很有信心的話.

前面 include 是給編譯器讀的前置處理指令, 告訴編譯器在進行編譯時, 要將哪些函式庫含括進來. 注意, C 程式的每一個敘述都要用分號結尾, 唯獨前置指令 include 與 define 不能用分號, 否則會編譯失敗.

最常用的函式庫是 stdio.h, 此函式庫提供如 printf(), scanf() 等常用的標準 IO 指令. 另外一個常用函式庫 stdlib.h 主要是提供系統呼叫 system() 函式用, 例如要讓標準輸出入視窗 (即命令提示字元視窗) 不要一閃而逝, 而是停住出現 "請按任意鍵繼續 ... " 以便觀察輸出結果的話, 就要呼叫 system("pause") 來達成. 不過 Dev C++ 編譯器即使沒有載入此函式庫也會自動停住等待按任意鍵, 呼叫 system("pause") 反而會停住兩次 :


故用 Dev-C++ 開發時若不需要其他系統呼叫, 其實不需要含括 stdlib.h. 系統呼叫 system() 可以讓程式執行作業系統指令, 例如 DOS 指令 dir, 如下範例會將程式所在目錄之檔案列表存入 dir.txt 檔案中 :

#include <stdio.h>   //載入標準輸出入函式庫
#include <stdlib.h>  //載入標準系統函式庫
int main() {
system("dir > dir.txt");
return 0;
}

某些編譯器即使沒有用 include 將 stdio.h 與 stdlib.h 含括進來, 還是可以呼叫 printf() 與 system() 等函式, 那是因為編譯器會自動載入此二函式庫之故. 為了移植的相容性方便, 還是照規定使用 include 為宜. 特別是使用指標時常需要呼叫動態配置記憶體的函式 malloc() 與 free(), 這兩個函式都放在 stdlib.h 裡面, 一定要含括進來才能使用.

含括進來的函式庫因為都擺在最前面, 故又稱標頭檔 (header files). 在 Dev-C++ 編譯器裡, 所有內建函式庫放在 C:\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include 下 :


進行編譯時, 指定的函式庫檔案就會被載入取代 include 指令. 最後是關於主程序 main() 的傳回值 int 與參數 void, 這兩個都沒有加的話, 在 Dev-C++ 都不會編譯錯誤, 不過為了可移植性, 還是加比較好.

為了編輯方便, 也可以將自己常用的程式片段做成樣板, 要用時可以立刻插入程式中, 點選 "工具/編輯器選項/插入程式碼", 按 "新增", 在項目名稱欄中為此樣板取名, 然後將程式片段貼到下方輸入框, 按確定即可 :


要插入樣板, 點選 "編輯/插入文字" 或第二排工具列最左邊的插入鈕, 即可挑選要插入之程式片段 :


雖然我學 C 的主要目的是為了掌握 Arduino 的嵌入式應用, 但因為去年用 Java 幫公司寫的大量數據擷取分析程式執行效能普普, 我打算將 Java 的數據處理函式庫改寫成 C 語言版本, PK 一下到底 C 語言在效能上有多優越. 關於 C 歷四十餘年而不衰, 且越來越紅火, 參考 :

# C 語言秘技 (1) – 使用 sscanf 模仿正規表達式的剖析功能 (作者:陳鍾誠)

此文提到用 sscanf 來模仿正規表示法, 正好用得上. 誠如此文作者所言, 程式語言如過江之鯽, 今日之星轉眼成昨日黃花, 而 C 因為擁有指標功能, 使其兼具高階與低階語言雙重身分, 寫驅動程式少不了它, 故能歷久不衰, 學習 C 的投資報酬率要以一輩子來衡量, 而不是十年二十年, 更何況 C 是掌握 Linux 內核的必殺技, 非學不可.

其他參考資料 :

# 在 C 程式中,使用 Regex (Regular Expression) library
# Using Regular expression in C/C++ 
# C 語言,使用 Regular Expressions
# 正規表示法:規則篇 (這個好)


2015年11月24日 星期二

第 47 周記事

本周六 (11/21) 公司福利會辦體育活動, 地點在駁二特區一帶. 之前報名時有想要帶菁菁去, 但後來想到段考又快到了, 好像聽說補習班又要魔訓, 所以就沒報名. 前幾天菁菁才說魔訓是周日啦, 我說好吧, 看天氣再說. 結果週六早上下起毛毛雨, 就打消騎腳踏車去的念頭, 菁菁就讓她繼續睡. 出發時雨稍停, 但騎到河東路又開始下小雨了. 到鹽埕埔站放好機車, 沿著活動路線走進駁二特區 :


沿路有兩站要簽名領抽獎券 (這是最重要的, 哈), 然後右轉越過鐵道故事館就是捷運哈瑪星站, 將摸彩券投入箱中就大功告成了. 但這時才剛過九點而已, 要十點半才抽獎, 我好像太早來了哩. 既然來到哈瑪星, 乾脆去我的母校中山大學晃一圈吧! 畢業後就很少有機會來這邊了. 走不到十分鐘就到西子灣隧道口, 以前讀書時都是騎機車走大門, 幾乎沒走過隧道呢!


 

看這隧道內壁, 我想開鑿年代應該很久遠了, 可能是日據時代吧. 隧道是一種很科幻又很神祕的建物, 讓人聯想到時光機器, 電影裡面回到過去或穿越未來總會看到它. 隧道盡頭就是中山大學校園了, 沒想到一晃, 畢業已十多年了. 其實我跟這個第二母校感情不是很深, 因為我只是要進修外文才來念書的, 學歷對我來說已經不是很重要. 不需要社團, 不需要宿舍, 不需要整天在學校晃, 當然也就沒有深厚的感情了. 

在校園逛一圈就循原路回到哈瑪星站, 這時已經有許多同事聚集, 等待抽獎了. 除了抽獎, 還有一碗阿婆冰, 以及一個帕莎蒂娜的酒釀桂圓麵包. 重頭戲是抽獎, 我手氣不錯抽到 1800 元的二獎, 回到家菁菁竟然說, 如果她有去的話一定抽到一獎.

活動結束後我沿著五福路轉成功路, 想說既然來到這區域, 順便去市圖總館好好搜刮一下, 上回匆匆逛了一下不過癮. 這次一共借了六本 TCP/IP 與網路相關的書.

回程經過同盟路發現一個新建築 : 黃金波蘿城堡, 門口有很多排隊參觀的人, 回來一查原來是鳳梨酥廠商維格餅家的觀光工廠, 適合親子共遊參觀, 不過小狐狸們已經不是那個年紀了, 菁菁勉強還會想去吧!

#  黃金波蘿城堡


因為菁菁要魔訓, 本周只有姐姐跟我回鄉下. 週日(11/22) 爸以前的同事娶媳婦, 上週是菁菁, 這次換姐姐吃喜酒啦! 而且這次有冰, 通常只有夏天的喜宴才會出水果+冰, 可能今年又是暖冬, 這幾天非常熱的關係.


2015年11月18日 星期三

好書 : 兩本 Wirshark 的中文書

最近因為研究 ESP8266 網路連線的關係, 發現自己對網路了解不夠, 加上工作上要用到 TCP/IP 的東西, 所以去市圖借了兩本協定分析軟體 Wireshark 的書, 打算好好地補強這方面的知識. 以往我都專注在應用層面的東西, 對於這些底層的東西興趣缺缺, 例如有一陣子公司鼓勵考證照, 我寧可去考 Java 認證, 也不要去考 CCNA. 總之, 我當時覺得, 路由器設定之類的東西好死板, 讀來味如嚼蠟. 但現在見解不同了, 從終端的手機, 到雲端的伺服器, 通通要用到 TCP/IP, 如果只有皮毛的認識, 恐怕要玩應用也玩不起來.

這兩本都是翻譯書, 第一本譯自 No starch press 的 "Practical Packet Analysis" :

# 碁峰-實戰封包分析 : 使用 Wireshark

Source : 博客來

這本書很受歡迎, 已經是第二版了, 還出現在維基百科的延伸導讀項目下, 參閱 :

# Wiki : Wireshark.

此書的特色如其書名, 強調實戰, 後半部 (8~11 章) 提供各種日常網路管理會遇到的實際案例, 前半部 (1~7 章) 則是介紹網路分析的基礎知識. 書中的範例檔案可在出版社網站下載 :

# http://www.nostarch.com/packet2.htm

第二本書譯自日本人久米原榮與上田浩的著作, 其實這本我兩年前想寫 Java 網路程式時早以前就借過, 但一直沒時間閱讀. 這本書是以主題條列方式編輯, 所以不一定要從頭依序讀到尾, 比較像是手邊可隨時查閱的工具書.

# 博碩-Wireshark 網路協定分析與管理
Source : 博客來

Wireshark 是採用 GNU 授權的免費開源軟體, 其前身是 Ethereal, 由 Gerald Combs 於 1997 年開始研發, 後來吸引許多高手加入開發團隊. 不過當 Gerald Combs 於 2006 年離開 NIS 公司跳槽到另一家公司時, 由於 Ethereal 是 NIS 公司的商標, 所以就改名為 Wireshark 了.


2015年11月16日 星期一

ESP8266 網頁伺服器 AT 指令測試

七月底對 ESP8266 進行 AT 指令測試時, 對於伺服器部分僅做了簡單的 PING 及與 Java client 程式的 TCP 連線測試, 沒有進行網頁伺服器的測試, 參考 :

# ESP8266 WiFi 模組 AT command 測試

今天看到 alselectro 的這篇文章, 介紹使用 AT 指令來測試 ESP8266 網頁伺服器功能的方法 :

# WiFi Module ESP8266 – 2. TCP CLIENT /Server mode

晚上就按圖索驥, 依照這篇描述來測試看看. 關於 AT 指令語法參考 :

# ESP8266 Serial WIFI Module
# https://github.com/espressif/ESP8266_AT/wiki/AT_Description

首先, 做為伺服器用時, ESP8266 必須工作在 STATION (mode=1) 或 STATION+AP (mode=3) 模式, 因為這樣它才會從 DHCP 獲得一個區網 IP (作為區網中的一台主機) :

AT+CWMODE=1


OK
AT+CIFSR

192.168.2.116

OK

這是 STATION 模式下所取得之區網 IP. 去 PING 它應該要能獲得回應 :

C:\Users\petertw89>PING 192.168.2.116

Ping 192.168.2.116 (使用 32 位元組的資料):
回覆自 192.168.2.116: 位元組=32 時間=876ms TTL=255
回覆自 192.168.2.116: 位元組=32 時間=65ms TTL=255
回覆自 192.168.2.116: 位元組=32 時間=70ms TTL=255
回覆自 192.168.2.116: 位元組=32 時間=77ms TTL=255

192.168.2.116 的 Ping 統計資料:
    封包: 已傳送 = 4,已收到 = 4, 已遺失 = 0 (0% 遺失),
大約的來回時間 (毫秒):
    最小值 = 65ms,最大值 = 876ms,平均 = 272ms  

如果是在 STATION+AP 模式下, 將獲得兩個 IP :

AT+CWMODE=3

OK

AT+CIFSR

192.168.4.1         (SoftAP 的 IP)
192.168.2.116     (Station 的 IP)

OK

其中第一個 IP=192.168.4.1 是 ESP8266 作為 SoftAP 之 IP, 僅作為網路接取點用, 無法作為主機使用. 第二個 IP 192.168.2.116 則是作為 STATION 用, 從 DHCP 所分派而得之 IP, 在區網中做為其他主機的伺服器要用到的就是這個 IP. 如果把 ESP8266 設為 AP 模式, 那麼就只剩下這個 SoftAP 的 IP 了 : 

AT+CWMODE=2

AT+CIFSR

192.168.4.1

OK

這個 SoftAP 的 IP 在區網中 PING 不到 :

C:\Users\petertw89>PING 192.168.4.1

Ping 192.168.4.1 (使用 32 位元組的資料):
要求等候逾時。
要求等候逾時。
要求等候逾時。
要求等候逾時。

192.168.4.1 的 Ping 統計資料:
    封包: 已傳送 = 4,已收到 = 0, 已遺失 = 4 (100% 遺失),


搞定工作模式後 (即須在模式 1 或 模式 3), 還有一個必要的設定要做才能啟動伺服器, 那就是開啟多重連線, 因為所謂伺服器就是要服務許多客戶端的連線要求的 (但 ESP8266 同一時間最多只能接受 6 個連線) :

AT+CIPMUX=1

OK

開啟多重連線後, 才可以啟動 TCP 伺服器, 其 AT 指令需輸入兩個參數, 第一個參數必須為 1 (0 的話是關閉伺服器), 第二個參數是要開啟的埠號, 一般網頁伺服器為 port 80, 當然也可以開啟不是專用 (well-known) 與註冊 (registered) 的埠號, 例如 8080 :


AT+CIPSERVER=1,80

OK

如果是在單一連線下開啟伺服器功能, 會收到 ERROR 回應 :

AT+CIPSERVER=1,80


ERROR

好, 啟動伺服器後, 便可用手機, 平板, 或電腦連線到與 ESP8266 所連的相同 AP (這樣才會在同一區網內), 啟動瀏覽器, 在網址列輸入伺服器的 IP 位址 (此處是 192.168.2.116), 我是從手機連線的, 這時瀏覽器會停在那邊, 不會看到任何內容 (因為要等 ESP8266 伺服器回應才知道要呈現啥內容啊!) :


這時在序列埠監視視窗會看到 ESP8266 收到來自手機的連線要求 (Link), 可看到手機瀏覽器傳來的 HTTP 標頭 :

Link

+IPD,0,498:GET / HTTP/1.1
Host: 192.168.2.116
Connection: keep-alive
x-wap-profile: http://wap1.huawei.com/uaprof/HONOR_H30-L02_Global_UAProfile.xml
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Linux; Android 4.4.2; H30-L02 Build/HonorH30-L02) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
Accept-Encoding: gzip,deflate
Accept-Language: zh-TW,en-US;q=0.8
X-Requested-With: com.android.browser


OK

注意在 +IPD 後面的那個數字, 就是代表連線的通道編號, 此處為通道 0, 後面的 498 表示收到 498 個字元. 這時若用 AT+CIPSTATUS 去查看連線狀態 :


AT+CIPSTATUS

STATUS:3
+CIPSTATUS:0,"TCP","192.168.2.102",38679,1

OK

可以看到目前有來自 192.168.2.102 (就是我的手機連上 WiFi 所獲得的無線區網 IP) 埠號 38679 的一個 TCP 連線, STATUS 為 3 表示 Connected. 最後的 1 表示 ESP8266 目前是作為 Server (0 表示 Client), 參考 :

# https://github.com/espressif/esp8266_at/wiki/CIPSTATUS

接下來我們必須在伺服器連線逾時 (timeout) 之前送出回應給客戶端, 這個逾時計時器預設是 180 秒, 可用 AT+CIPSTO? 查詢 :

AT+CIPSTO?

+CIPSTO:180

OK

當然也可以用 AT+CIPSTO=timeout 設定, 逾時秒數範圍 0~28800.

回到送出回應, 首先要用 AT+CIPSEND 指令告訴 ESP8266 要送出的回應長度, 以便它能組建 TCP 訊息. 例如伺服器回應 "Hello!", 此字串含有 6 個字元, 但要額外加上 "\r\n"  這兩個跳行字元, 一共是 8 個字元, 所以 AT 指令 :

AT+CIPSEND=0,8

這時 ESP8266 回應大於符號, 表示可以開始傳送資料, 接著送出 Hello! :

> Hello!
SEND OK

看到 SEND OK 表示傳送成功, 但這時瀏覽器還看不到伺服器回應, 必須關閉 TCP 連線才會收到回應 :


AT+CIPCLOSE=0    (關閉 TCP 連線)


OK
Unlink
Link

+IPD,0,357:GET /favicon.ico HTTP/1.1
Host: 192.168.2.116
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Linux; Android 4.4.2; H30-L02 Build/HonorH30-L02) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
Accept-Encoding: gzip,deflate
Accept-Language: zh-TW,en-US;q=0.8
X-Requested-With: com.android.browser


OK
Unlink

這時手機瀏覽器才會收到伺服器回應的 "Hello!" :


再用 AT+CIPSTATUS 去查詢 IP 連線狀態, 可知連線已中斷 (4=DISCONNECTED) :

AT+CIPSTATUS

STATUS:4

OK

以上便是網頁伺服器的 Server-Client 互動流程.

最後, 若要關閉伺服器, 停止網頁服務, 同樣是下 AT+CIPSERVER 指令, 但只要給一個參數 0 即可 :

AT+CIPSERVER=0

we must restart

這表示關閉伺服器後必須重啟 ESP8266 :


AT+RST


OK
bB��Sb禔S��"�芀�侒��S��
[Vendor:www.ai-thinker.com Version:0.9.2.4]

ready

AT+CIPMUX?

+CIPMUX:0

OK

可見, 重啟後多重連線也自動被關閉了.