WIN thrift 庫 相容XP系統

2021-07-24 19:01:47 字數 3126 閱讀 7125

因為工作上需要開發一款c/s架構的軟體, 在客戶端和伺服器之間通訊方式上, 經過幾番思考之後決定採用thrift 庫作為通訊工具.

thrift庫的呼叫採用的函式介面的方式, 設計者設計之初希望將網路傳輸層, 和資料協議層徹底隔離. 網路通訊的使用如同在本地呼叫一樣. 這種設計理念是非常驚豔的. 讓開發者更加專注於業務邏輯上. 這也意味著thrift 庫的 同步呼叫將成主流. 對於網路通訊而言, 同步通訊曾經是揮之不去的噩夢. 但是thrift 卻提供了一種非常優雅的方式處理: 將所有網路通訊問題封裝成異常.

thrift 本身並沒有提供身份識別機制. 伺服器本身無法自動識別客戶端身份. 開發者如果需要實現身份識別機制, 則需要在每個介面函式上提供身份識別id. 

例如: sayhi(const string t_ssid ); 

t_ssid 即為身份識別id. ssid 在客戶端第一次連線伺服器時, 由伺服器生成的特定字串特徵碼. 客戶端和服務端各存乙份. 客戶端向服務端申請服務時 服務端即可根據客戶端所提供的id 資訊, 選擇是否提供服務.

thrift 庫本身支援常用基礎的型別, 資料結構, 類為了實現大資料量的傳輸, 例如需要將一張資料庫表傳輸出去, 單純使用資料結構是非常糟糕的. 這時候就必須考慮資料序列化的處理方式. 例如將乙個類的資料全部轉化成 json 格式的string進行傳輸. 

筆者做過乙個基本的測試, 將size為10w 的string型別傳輸到伺服器,在回傳到客戶端 , thrift 均可以完全勝任

由於thrift介面不支援引用,或者指標, 介面層僅接受乙個引數作為返回值. 由於返回引數本身需要負責資料的傳輸工作, 將錯誤資訊通過返回引數方式顯然太過奢侈.同時也將大大增加程式設計的複雜程度. 由於thrift 支援使用者自定義異常, 對於可使用主動丟擲異常的方式來傳輸錯誤資訊.

由於thrift 每次在返回前都會捕獲異常. 使用者自定義異常放行. 其他異常將主動捕捉,並且報錯. 報錯後伺服器將對當前客戶端連線拒絕伺服器, 甚至導致整個thift 伺服器伺服器卡死的情況發生. 這也就要求開發者在伺服器端要求有著嚴格的異常保護機制. 由於thrift伺服器異常錯誤將無法提供錯誤觸發原因. 將導致軟體異常難以除錯. 筆者的做法是在thrift層執行 std::exception 異常捕獲. 主動將所有非使用者自定義異常捕獲, 並且將程式 abort()掉.以方便快速定位軟體錯誤.

客戶端的thrift 客戶端呼叫本身不具備多執行緒的保護機制. 在客戶端使用多執行緒通訊時, 開發者需要使用多執行緒保護機制. 否則伺服器非常容易被客戶端引發異常錯誤. 導致拒絕服務

由於thrift 預設使用了win7 的網路通訊庫, 導致thrift無法相容xp. 筆者使用的thrift 0.9.2 版本庫, 在xp 下執行時, 系統提示無法定位 ws2_32.dll , 經過多番討論和原始碼研究之後, 發現這是官方的乙個bug所致. 之前也有很多人提及到這個bug的存在, 但是因為國外 xp的覆蓋率太低, 這個bug 到thrift 0.9.3 均未解決.

首先定位thrift原始碼中的 

thrift-0.9.2\lib\cpp\src\thrift\windows\winfcntl.cpp

此檔案根據系統的版本的不同, 定義不同的網路通訊方案. 通過原始碼可得知,其實官方的thrift在開發之初是有直接支援xp 系統的, 只是因為bug 的原因, 所有的系統均呼叫了 

* wsapoll(fdarray, nfds, timeout);* 這個函式, 導致軟體無法在xp執行. 

既然知道了這個原因, 從最小修改**的角度出發, 既然thrift 原始碼無法對系統 _win32_winnt 有效的識別, 那麼直接強制thrift 均採用 xp 模式下的網路通訊方案,即可解決相容xp 的問題

/// 需要遮蔽此行

#if _win32_winnt <= 0x0502 //xp, server2003

/// 需要遮蔽此行

int thrift_poll(thrift_pollfd *fdarray, ulong nfds, int timeout)

//write (out) socket

else

if((fdarray[i].events & thrift_pollout) == thrift_pollout)

} timeval time_out;

timeval* time_out_ptr = null;

if(timeout >= 0) ;

time_out_ptr = &time_out;

} else

int sktready = select(1, read_fds_ptr, write_fds_ptr, null, time_out_ptr);

if(sktready > 0)

} return sktready;

}//// 需要遮蔽 , 此巨集定義根據系統版本採用不同的通訊機制

#else //vista, win7...

int thrift_poll(thrift_pollfd *fdarray, ulong nfds, int timeout)

#endif // winver

//// 需要遮蔽

通過遮蔽以上幾行**, 親測可實現相容xp 的功能. 但是聽大神提示說, xp 模式下的網路效率 比 採用 win7 wsapoll(fdarray, nfds, timeout); 系統庫的效率要低. 畢竟xp 是2023年的產品.

通過**交流, 有大神提出在現有的基礎直接採用boost 網路庫的方案, 以解決通訊效率的問題.

int thrift_poll(thrift_pollfd *fdarray, ulong nfds, int timeout) 

; // 下列select庫為boost網路庫

return select(1, &read_fds, &write_fds, &except_fds, &time_out);

}

XP引導Ubuntu Ubuntu手記之系統配置

因為之前就已經試著裝過 unbuntu的硬碟安裝 因此一切都是輕車熟路。這次希望能向原來未曾解決的問題發起衝鋒 使用xp的引導程式來引導ubuntu。照老規矩,安裝時不將grub寫入到mbr,先讓ubuntu先沉睡在系統中,然後再配置windows xp來引導ubuntu。經過一番探索發現理論上應該...

mysql user objects 資料庫系統表

access的系統表是msysobjects msysaccessobjects msysaces msysimexcolumns msysimexspecs msysobjects msysqueries msysrelationships sql server的系統表是sysobjects sq...

摘 PC客戶端 XP相容性調查

解決方案 需要安裝以下3個補丁 已經整合到安裝包中 系統hotfix 僅僅xp sp2需要安裝 net framework hotfix 建議所有系統都安裝,使用64位補丁包 調查結果 通過調整系統的顯示卡加速模式,可以改變視窗的渲染模式,讓視窗變得不透明 解決方案 在xp系統中,使用cpu模式渲染...