6.3 客戶機程式2—增加錯誤檢查
我們的第二個客戶機程式將像第乙個客戶機程式一樣,但是將修改它們,考慮錯誤出現的可能性。「將錯誤檢查作為讀者的練習」這樣的專案在程式設計文獻中相當常見,這或許是因為檢查錯誤相當令人討厭。但是,我贊同這種觀點,即mysql
客戶機程式應該測試錯誤條件
並適當地進行回應。由於某種原因,返回狀態值的客戶機庫的呼叫做這些事情,而且您要承擔忽略它們的後果。您最終還是要試圖捕獲由於沒有錯誤檢查而出現在程式中的錯誤,這些程式的使用者會對程式執行如此不規律感到奇怪。考慮我們的程式,客戶機程式1。如何知道它是否真正連線到伺服器上?可以通過檢視伺服器的日誌,找出與執行程式時間相應的connect和quit事件:
這條訊息表示根本沒有建立連線。不幸的是,客戶機程式1沒有告訴我們出現的這些結果。實際上它不能。它不能實現任何錯誤檢查,所以它甚至不知道自己發生了什麼事。無論如何,當然不一定必須檢視日誌來尋找是否能連線到伺服器!讓我們立刻改正它。在mysql客戶機庫中返回值的例程基本上以下列兩種方式之一表示成功或失敗:
■ 成功時,值的指標函式返回乙個非null 指標,失敗時返回null(在這裡null 的意思是「c null 指標」,而不是「mysqlnull 列值」)。迄今為止,我們使用的客戶機庫的例程mysql_init() 和mysql_real_connect() 都用返回連線處理程式的指標來表示成功, null 表示失敗。
■ 整型數值的函式一般成功返回0,失敗返回非0。不要測試特定的非0值,如- 1。因為當失敗時,並不保證客戶機庫函式返回任何特定的值。有時,您可能會看到像如下的較舊的錯誤地測試返回值的**:
這個測試可能工作,也可能不工作。mysqlapi 不將任何非0錯誤的返回指定為特定的值,而只判斷它(顯然地)是否為0。這個測試應該寫成下面兩段之一:
或如下所示:
這兩個測試是等價的。如果審核mysql的源**,則可以發現,它基本上用第一種形式測試,因為這編寫起來更簡短。
不是每個api 呼叫都返回值。我們使用的另乙個客戶機例程mysql_close() 就不返回值(它如何失敗?失敗了又如何?無論如何,都要進行連線)。
當客戶機庫呼叫失敗,並且需要有關失敗的詳細資訊時, api 中的兩個呼叫都是有用的。mysql_error() 返回包括錯誤資訊的字串,而mysql_errno() 返回數值**。應該在錯誤出現以後立刻呼叫它們,因為如果發布另乙個返回狀態的api 呼叫,則從mysql_error() 或mysql_errno() 獲取的任何錯誤資訊都將來自於後面的呼叫。
一般來說,程式的使用者檢視錯誤字串比檢視錯誤**更有啟發。如果只報告兩者中的乙個,則建議報告字串。出於全面考慮,本章的這個樣例報告兩個值。考慮前述的討論,我們將編寫第二個客戶機程式,即客戶機程式2。它類似於客戶機程式
1,但是適當地增加了錯誤檢查**。原始檔client2.c 如下所示:
這個錯誤檢查的邏輯是,如果失敗,則mysql_init() 和mysql_real_connect() 都返回null。請注意,儘管這個程式檢查mysql_init() 返回的值,但是,如果它失敗,卻不呼叫錯誤報告函式。這是因為當mysql_init() 失敗時,不能假設連線處理程式包括任何有意義的資訊。
相反,如果mysql_real_connect() 失敗了,則連線處理程式並不反映有效的連線,但是的確包括傳送給錯誤報告函式的錯誤資訊(不要將該處理程式傳送給任何其他的客戶機例程!因為它們一般假設是乙個有效連線,所以您的程式可能崩潰)。編譯和連線客戶機程式2,然後試著執行它:
% client2
如果客戶機程式2沒有別輸出,則連線成功。另一方面,可能會如下所示:
這個輸出表示沒有建立連線,並說明為什麼。或者,它還表示我們的第乙個程式,即客戶機程式1,沒有成功地連線到伺服器(畢竟客戶機程式1使用同樣的連線引數)!而在那時我們不知道,因為客戶機程式1沒有錯誤檢查。而客戶機程式2做檢查,所以當出問題時,它可以告知我們。這就是應該始終測試api 函式返回值的原因。
mysql郵件清單問題經常是與錯誤檢查有關的。典型的問題是「當傳送這個查詢時,為什麼我的程式崩潰了?」或「我的程式怎麼沒有返回任何東西?」在許多情況下,在查詢發布以前,有疑問的程式不檢查在發布該查詢前是否成功地建立了連線,或者不檢查在試著檢
索結果前確保伺服器成功執行該查詢。不要假定每個客戶機庫都呼叫成功。
本章下面的例子完成錯誤檢查,而且也應該這樣。看起來它好像有更多的工作,但是從長遠地執行來看,它的工作實際上是少的,因為您化費了更少的時間來捕獲錯綜複雜的問題。在第7章「perl dbi api」和第8章「php api」中,也使用這種檢查錯誤的方法。
現在,當執行客戶機2的程式時,假設看到拒絕訪問( access denied)的訊息。如何改正這個問題呢?一種可能是將主機名稱、使用者名稱和口令的#define 行更改為允許訪問伺服器的值。這是有好處的,在這個意義上,至少應該能做乙個連線。但是,這些值是程式中的固定編碼。所以筆者建議不要用這種方法,特別是對口令值。當將自己的程式編譯為二進位制格式時,您可能認為口令隱藏起來了,但是,如果有人在程式上執行strings,則它根本隱藏不住(更不用說明讀取訪問原始檔的人根本不用做一點工作,就可以獲取口令)。
在「客戶機程式4—執行時獲取連線引數」一節中我們將處理訪問的問題。首先,筆者
想說明編寫連線**的一些其他方法。
配置zabbix客戶機
配置zabbix客戶機 1.1 問題 本例要求新準備一台centos 7虛擬機器,作為zabbix客戶機,完成下列任務 1 配置新虛擬機器svr8 安裝zabbix agent軟體包 允許zabbix server服務端採集資料 啟動zabbix agent服務 1.2 步驟 實現此案例需要按照如下...
瘦客戶機及其應用
近年來,瘦客戶機 機群 得到廣泛應用。在學校 機關和中小企業,都有瘦客戶機 機群 應用的例項。所謂 瘦客戶機 thin clients 是指,它的所有軟體和資料都儲存在網路伺服器上的計算機。資料和應用軟體的集中儲存和分配,具有許多優點,能夠節約大量的系統購置和管理成本。瘦客戶機系統允許人們在不同地點...
xen安裝ubuntu客戶機
dom0 ubuntu12.04 amd64 xen 4.1.2 domu ubuntu12.04 安裝配置檔案ubuntu1204.cfg kernel usr lib xen boot hvmloader builder hvm memory 512 vcpus 4 shadow memory ...