==> 2008年10月12日 星期日 <==

啓明星




今日瀏覽網頁,無意中查左下啓明星,先知道,原來啓明星即系金星,亦系古時所講既「太白」或者「長庚」。傍晚出現時就稱之為「長庚」,清晨出現時稱「啟明」。其它既稱呼仲有:殷星,大正,營星,明星,觀星,大衣,大威,太(白+皋),終星,大相,大囂,爽星,太皓,序星。

可以通過維基百科查詢到更詳細的金星資料




==> 2008年6月23日 星期一 <==

Mingw 下 編譯 wxSQLite




1. 初始條件

  首先確定環境變量只有 Mingw 的路徑而沒有 msys 的路徑,因為使用 msys 編譯會有些問題。

2. 修改 makefile

  打開 wxsqlite3\build 下的 makefile.gcc,設定你需要的條件,如若妳不需要加密模塊並且擁有自己的SQLite3源代碼目錄,妳可以設定 SQLITE3_DIR

3. 編譯

  make -f makefile.gcc clean
  make -f makefile.gcc




==> 2008年6月19日 星期四 <==

分佈式版本控制系統SVK搭配TortoiseSVN的使用




  SVK與Linus所開發的Git相似,是一種分布式的版本控制系統,但它並不是完全從頭編寫的版本控制系統,而是基于 Subversion 的分布式的版本控制系统。如 CVS,Subversion 這些集中式管理系统存在对唯一的版本库过分依赖的缺陷:一旦不能正常连接到集中式的版本库,整个系统陷入瘫痪。分布式的版本控制系統最大的好處在于可以维护分布式的版本库,分散的开发人员可以通过 SVK 建立远程的 CVS,Subversion,P4 协议的版本库镜像,选择工作在自己合适的镜像版本库,这个镜像甚至可以是本地的,整个工作可以离线进行,然后在需要的时候同步镜像版本库到主版本库。

1. 假定條件

  首先假定妳已經熟悉所有SVN的操作,
  再假定 c:\svnlib 為SVN的對外的倉庫根目錄,
  假定妳機子已經安裝好SVN服務,
  若 c:\svnlib 下有一項目 test 倉庫(c:\svnlib\test), 假定妳能正確通過Tortoise讀寫其項目文件( svn://localhost/test ),
  假定網絡版本庫為 svn://192.168.1.100/MyProject.

2. 初始化

  在 c:\svnlib 下創建目錄 svklib (目錄名隨便你定義)
  在 c:\svnlib\svklib 使用 TortoiseSVN 右鍵在此創建版本庫(注意:這一步是鏡像的基礎!因為SVK用的就是SVN的版本庫)

  SVK是默認在 "C:\Documents and Settings\當前用戶名\.svk\Local" 創建鏡像倉庫的,所以需要先把鏡像倉庫位置重定位到你需要的位置( 當然, 如果妳喜歡默認的位置, 那你可以跳過這一步 ) 

  svk depotmap --relocate // c:\svnlib\svklib

  上面這行命令有一個概念, 就是depot-map -- 倉庫表, 妳可以使用svk depotmap 建立多個鏡像倉庫, 而不重定位, 這裡為了方便解說並盡量減少旁枝末節的繁雜概念問題而直接把默認位置重定位了. "//" 是一個倉庫名, 類似於Linux的那個根目錄, SVK把默認路徑當作根目錄, 所有的鏡像倉庫均建立在根目錄以上.

  妳用 svk depotmap --list 命令就可以看到SVK的根目錄被定位到 c:\svnlib\svklib 下了

  接下來我們建立一個鏡像目錄.
  我們必須建立一個鏡像目錄, 因為所有提交到此鏡像目錄的操作均被認為提交到網絡上的原始版本庫!!!

  下面這裡的 "-m test" 是設定此次操作的提交註釋,具體的詳情請參考SVK的幫助。

  svk mkdir //mirror -m test

3. 日常使用

  镜像! 把網絡版本庫鏡像下來.

  svk mirror svn://192.168.1.100/MyProject //mirror/MyProject

  同步! 注意: 這裡不需要再輸入那個網絡路徑了, 網絡路徑在上面進行鏡像時會記錄下來的!

  svk sync //mirror/MyProject

  成功!

  由於對鏡像目錄進行修改即相當於直接提交到網絡版本庫, 因此不能直接對鏡像版本庫進行修改, 所以必須新建一個本地的挎貝(分枝)! 注意!! 是必須!!

  svk mkdir //local
  svk cp //mirror/MyProject //local/MyProject

  接下來妳就可以使用TortoiseSVN的功能方便地對你剛才分枝下來的版本(//local/MyProject 即 svn://localhost/svklib/local/MyProject )進行取出\修改\提交了
  只是要記住, 妳所做的一切操作只能是修改妳的本地分枝, 即SVK源代碼目錄下面那個Local下的MyProject!

  當妳需要把修改提交到網絡原始數據庫時, 妳需要先更新鏡像目錄
  svk sync //mirror/MyProject

  再提交妳的代碼,此過程會自動 Merge 妳的修改到遠程版本庫。

  svk push //local/
MyProject

  記得, 修改鏡像庫時, 必須且只能使用SVK的方法, 否則更新不能被更新到網絡版本庫!

  各種關係及操作如下圖: 




==> 2008年6月17日 星期二 <==

Mingw 下編譯 gettext 0.17




  這兩天編譯gettext搞得焦頭爛額,機子裡裝了大量的開源工具,結果各種動態鏈接庫版本不一致,編譯工具不一致,導致編譯時老是不成功,後來乾脆寫個批處理,把 path 環境變量只設置為 mingw 及 msys 的Bin,把 include 中除 mingw 及 msys的路徑外(例如Gtk)全刪除,然後在Dos下使用以下的編譯命令一次編譯成功:

sh ./configure --enable-threads=win32 --with-libiconv-prefix=d:/sb/sdks/libiconv

==========
當前使用到的編譯環境變量(Mingw GCC4.21):

CPPFLAGS=-mno-cygwin -Wall -pipe -mthreads -fno-strict-aliasing
CFLAGS=-mno-cygwin -O2 -g -pipe -mthreads -fno-strict-aliasing
CXXFLAGS=-mno-cygwin -O2 -g -pipe -mthreads -fno-strict-aliasing
LDFLAG=-mno-cygwin




==> 2008年6月14日 星期六 <==

使用 OTL 連接 SQLite




  本文章假定妳熟悉SQLite數據庫,假定妳對OTL有 一定了解,假定妳所使用的操作系統為Windows平台。

  OTL 採用的是ODBC數據源機制,到 http://www.ch-werner.de/sqliteodbc/ 可下載到最新的SQLiteODBC數據源驅動。

  假定你已經創建了一個名為 MyTestDB 的數據源連接到你的數據庫,數據庫中有一表 Users, 表中有字段 id 及 value,id 为整型,value為字符串50個字節。

#include <iostream>
#include <string>


// 配置ODBC連接方式,其它方式可查看頭文件或文檔
#define OTL_ODBC
#include <otlv4.h>

otl_connect db; // 連接物件

void
test_select( void )
{


  otl_stream dbstream( 1 , " select * from Users " , db );
  int
     Usersid;

  char
     Usersvalue[ 50 ] = "" ;

  while
( !dbstream.eof() ) // 循環讀取記錄

  {
    dbstream >> Usersid >> Usersvalue;
    std::cout
      <<
"Users.id : " << Usersid

      <<
"Users.value : " << Usersvalue << std::endl;
  }
}


int
main()
{


  otl_connect::otl_initialize(); // 初始化OTL環境

  db.rlogon( "DSN=MyTestDB" );
  if
( db.connected )
  {


    test_select();
  }

  db.logoff(); // 斷開連接

  system( "PAUSE" ); // 暫停

  return 0 ;
}




==> 2008年6月13日 星期五 <==

數據包在互聯網




1.前言
  前段時間做一個NDIS網絡驅動,功能是修改IP包的IP地址并傳送到指定的機器,在測試時發現一個問題,假如在內網中傳送數據包到在內網的一台不同網域的機器上,數據包不能傳達,具體問題在[1]有詳
細說明。在 Google查了很多數據,經過多次測試,最終發覺,原來是路由器(Router)的問題。在這過程中,發現很多網友對數據包在網絡上的傳輸有誤解,因此我想對這個問題進行一次詳細的說明,以備以后的不時之需。
  網上有很多網友對以太網的理解是:數據包在互聯網是在IP層傳輸的,以IP地址來判斷地址并傳輸的。這是一個誤解,互聯網不認識IP協議層,只是由於現在有些寬帶運營商(ISP)使用了“釆用執行在協議層
的路由器”,所以導致出現由於 IP不在該路由器所控制的范圍則自動被放棄,我們看見的就是不符合IP協議的均會被放棄。這種做法好處是避免了廣播風暴問題,但同時又削弱了互聯網的功能,例如我們就不能直接把一個不釆用IP協議的數據包傳輸至互聯網某一個物理地址(MAC地址,下同)的機器。

2.互聯網

  當前互聯網釆用的是以太網,即釆用以太網交換機實現的,這種網絡的好處是,只要你知道網絡上某一機器的物理地址,即可以把數據包通過廣播傳輸到相應的機器上,但同時這樣也會造成廣播風暴,致使網絡癱瘓,當然這種情況是可以通過某些手段進行抑制的,下面會進一步說明。

2.1.以太交換機

  為了簡化模模型,我們先假設所有機器均以獨立IP連接到互聯網。(如圖)

 以太網交換機處於的是數據鏈路層,它只處理以太網頭,也就是說它只認識數據包的物理地址,舊式的交換機的處理過程是:只要數據包在互聯網某一個點發出數據包,數據包在經過每一個交換機時,交換機自動把數據包向所有端口廣播,這樣,通過一個又一個交換機的廣播,終端機的機器判斷該數據包的物理地址是否自身的物理地址,是就通知上層數據包的到達,否則直接掉棄。這種處理方法,在小數據量時很有效,但當有大量數據傳輸時,就難以保證了,由於交換機不停地廣播數據包,就會致使網絡由於廣播的數據太多而癱瘓。這時人們就想出了辦法,就是物理地址查詢機制:每一個從交換機輸入端的經過的數據包源物理地址將被存儲起來,然后當有數據包來臨時,就向每個端口查詢是否存在該數據包的目的物理地址,如果存在,則直接把數據包傳送往該端口,如果都尋找不到,則廣播該數據包。這樣就有效地抑制了大部分的數據包廣播了。

2.1.1.優點

2.1.1.1.增加協議靈活性

  例如你需要設計一個不使用IP協議的嵌入式設備,有人可能會說為什么不釆用IP協議?IP協議有更成熟的技朮,以及現成的各種函數例程。只要是做過工控、嵌入式設備、智能家居設備、寫過51程序或者是在DOS時代做過程序都知道,有大部分的項目對內存及空間的要求是非常嚴格的,其內存是寸金尺土,少几個字節就能換來整個產品成本下降數千元以至更多,通常一些嵌入式設備,需要的控制指令是很短的,只需要几個字節就足矣,沒必要攜帶龐大的IP頭。而且在互聯網上通過物理地址即可以把數據包傳輸到指定的設備,IP地址也就沒必要了。

2.1.1.2.准確到達目的地

  由以太交換網的結構及處理方式我們可以知道,數據包是可以通過物理地址直接到達目的地的,這也是為什麼有些技術書籍寫的可以通過數據包獲取源目的地物理地址的原理。物理地址類似於IP地址,IP地址代表的是互聯網上一個虛擬機器,而物理地址代表的是互聯網上一個實際設備,IP地址只有4位字節,而我們平常使用的物理地址是6位字節,擁有 281474976710656(281萬億)個地址,比起IP地址多多了,從當前情況來看,足夠各種計算機及設備都配備一個物理地址的,暫時也不需要擔心類似IP地址那樣的地址不夠問題。

2.1.2.缺點

2.1.2.1.沒有更多的控制參數

  以太網協議頭只有兩個物理地址及一個后續協議(或長度)參數。此缺點可以通過自定上層協議來實現更精細的控制要求來解決。

2.1.2.2.容易造成廣播風暴

  由於數據包釆用廣播來進行數據包傳輸,因此當各處傳送的數據包量大時,會導致網絡崩潰。此缺點可以釆用物理地址查詢機制來抑制。

2.1.3.路由器

  一些公司租用一倏寬帶后,希望能物盡其用,通常會把全公司的機器都搭上互聯網這趟快車,這時候就有几種方案:1、集線器;2、交換機;3、路由器。我們看下三種方案的優缺點:首先是集線器,嗯,這個方案效率有點低,當多個端口同時出現傳送或接收數據時,只能喊“My God”了,因此此方案不予釆用。剩下的兩個方案,各有各優點,只能見仁見智了,在出口IP不限制出口物理地址時,推荐釆用交換機以換取更大自由度否則就釆用路由器吧。
  路由器實際上跟以太網交換非常相似,只是功能更復雜了。路由器會自動根據網絡拓撲、負荷的改變及時維護該路由表,并擁有更強大的數據管理功能,例如防火牆、流量控制、自動撥號等,當然現在交換機也有這些功能的了,所以交換機跟路由器的功能很多時候重復了。當路由器找不到某一端口輸入的數據包對應的輸出端口時,即刪除該包。注意,這一點它跟交換機是不一樣的,交換機找不到時即廣播該數據包,因此,如果有一設備在路由器控制范圍內,而路由器不知道的話,那么該數據不會到達該設備!雖然路由器極好地抑制了數據包的廣播,但同時也損失了數據包到達准確地址的機會。
  同時,由於中國人口太多,過多的人口,過少的接入IP,導致網絡的發展畸形化,現在國內大部分中小規模路由器直接釆用了IP協議控制!!這一點導致了所有非IP協議數據包不能傳送!而且,就算明知道路由器控制的網域存在相應的物理地址,只要IP地址不對應,它也不進行傳送,結果可想而知,嵌入式設備這類就必須釆用 IP協議了,由此也帶來了設備成本的提高。釆用了IP協議,還可通過透明橋接來解決廣播技朮問題。但如果像我所釆用的那款路由器就慘了,它還把進出的數據包物理地址給修改了,這樣,內外就不能進行正常的UDP或者其它協議的數據傳輸了,只能通過中轉形式,如再買一倏電信或網通的寬帶,接一台計算機作中轉站,服務器長期維護一倏中轉站的TCP連接,然后所有外來數據均通過中轉站打包,傳送往服務器,再在服務器解包,再轉發相應端口。當然,這種修改數據包物理地址的方案,估計是為了針對現在寬帶運營商出現的封路由器而設計的,也是迫於無奈啊。

溫情提示:

  在國內,建議采用電信或網通的互聯網服務,目前就我所知,只有電信和網通是能讓你機子直接擁有公網IP的,雖然是動態的,也比其它的ISP如鐵通、視通等的內網 IP好,例如我使用的鐵通(後悔!),別人就不能根據我的出口IP直接連接到我的機子,也就是說我付的費用跟電信和網通一樣,但我卻只能擁有一半的功能,只能出不能進,如果需要外網能訪問我的機子,需要付一大筆的費用,很不划算。鐵通、視通這些是租用電信和網通的IP,然後采用分級路由器建立了一個龐大的局域網,因此所有出去的數據包的物理地址和進來的數據包的源物理地址均被修改為路由器的物理地址,也由於物理地址被修改,互聯網上別的設備或機器就不能通過物理地址定位我們的機子!同時由於路由器內網全部采用內網地址,因此只有鐵通或視通他們內部網的并用處於同一路由器級的用戶才能直接訪問相互的機子,其實就是局域網互訪,而因特網用戶是不能訪問你的機子的!當然,如果你不需要建立自己的網站、不需要別人訪問自己的機子、不需要建立自己的服務器的話,你家裡也沒有采用因特網的智能家居之類的嵌入式設備,這樣,鐵通、視通的安全性卻反而比電信和網通高,因為你不在公網內,被局域網保護起來了,特別是路由器有防火牆的情況下。如若你只能使用鐵通,那也不是沒辦法使你的機子公開的,只是方法就複雜多了,還需要一筆額外的費用,而且速度和穩定性沒有保障,那就是采用花生米的服務了。其實就是做了一個NAT轉換,或者是數據包的轉發,在這情況下,你的機子需要一直開著一個TCP連接,以維持數據的傳送。

[1] 偽IP如何實現與客戶機進行TCP通訊?
http://starofrainnight.blogspot.com/2008/04/iptcp.html




==> 2008年4月5日 星期六 <==

偽IP如何實現與客戶機進行TCP通訊?




-----------
* 軟件環境:

WinXP sp2

截取數據包的Ndis5.0驅動已經寫好。
在用戶層,能夠修改驅動發來的數據包的IP地址,客戶機也能接收到該數據包。

我這個軟件是用于模擬多客戶機與服務器連接實現數據傳輸的測試軟件。

-----------
* 硬件環境:

(33.33.33.33(假定是這個))    |—— 客戶機2 (192.168.1.105)
客戶機1——路由 (192.168.1.1)——|
                |—— 發送機 (192.168.1.100) (偽裝 99.99.99.99)

現在需要發送機偽裝IP 99.99.99.99 與兩客戶機進行TCP通信

在客戶機2安裝的Ethereal 檢測到發送機發來的IP為 99.99.99.99 數據包,物理地址(MAC)也為發送機的物理地址。

但 問題是,當客戶機2接收到第一次TCP握手包后,它返回的響應包雖然目的IP地址仍然是99.99.99.99,但物理地址卻是網關 192.168.1.1的物理地址!我再查看客戶機2的數據包,發現在它接收到發送機發送的握手包時,它先發送ARP數據包查詢了網關 (192.168.1.1)的物理地址再發到網關。也就是說,當客戶機發現接收的數據包IP與自己不在同一子域則自動把數據包發往網關,但現在問題是由于 發送的物理地址改變了,網關只能查詢正確的99.99.99.99的物理地址,那這時候,數據包也就不能再返回偽裝的發送機上了。于是TCP連接被逼中 斷。

而且,兩客戶機均開啟了防火牆,不能使用ICMP實現數據包路徑轉移。

我嘗試發送ARP包去修改客戶機2的ARP緩沖,但沒用,不同一子域的IP地址不會受到緩沖,結果IP包依然發往網關。

有何方法可以實現發送機與兩客戶機用偽IP通信?鬱悶中……