2011-08-08 34 views
2

我正在爲基於平板電腦的HTML客戶端編寫一個基於Delphi的Windows服務器。Indy IdHTTPServer GET響應參數隨機缺失

大多數文件都是未經處理的,就像您期望的網絡服務器一樣,但少數特殊關鍵字被解釋爲與服務器上的其他軟件接口的特殊命令。

大多數時候,一切都很好。但隨後,看似隨意,我會得到一個訪問衝突,並且它將嘗試檢索其中一個GET參數。

這是快把我逼瘋了,所以我封裝整個事情分解成一個功能,剛開始測試的TIdHTTPRequestInfo數據的存在(在這裏顯示爲公共財產請求裏面的類):

function TELSCommand.GETValue(key:AnsiString):AnsiString; 
begin 
    if not Assigned(Request) then begin 
     Log.e('WHERE IS REQUEST?'); 
     Result := ''; 
     Exit; 
    end; 

    if not Assigned(Request.Params) then begin 
     Log.e('WHERE IS REQUEST PARAMS?'); 
     Result := ''; 
     Exit; 
    end; 

    if (Request.Params.IndexOfName(key) >= 0) then 
     Result := Request.Params.Values[key] 
    else 
     Result := ''; 
end; 

我沒有真正期望兩個Assigned()檢查中的任何一個被觸發,但隨機地,第二個會被觸發,我會看到「哪裏是請求參數?在碰到F5後我的日誌文件中(慢慢地,我沒有敲打服務器)。

當我在塊內部放下一個斷點並檢查請求的值時,整個TIdHTTPRequestInfo結構中將填充默認的空數據。如果我檢查瀏覽器以查看它發送了什麼請求,這就是我所期望的...(例如,通常只是請求「/details?id = 222」)。

我應該注意到,我正在開發Windows 7 64位,所以我經常偏執這樣的事情是由它造成的。我不止一次碰到了因64位古怪而導致的障礙。

附加信息:印9,德爾福2007年

希望這是不夠清楚明白。我沒有找到具體的答案,因爲我沒有提供足夠的;我只是在尋找從這裏去哪裏的建議。非常感激! :)

+0

如果你真的「沒有找到具體的答案」,那麼你就錯了 - 我已經投票結束了*不是真正的問題*。你有Indy源代碼,所以繼續調試。找到「Params」應該分配的地方。逐步瞭解如何發生。與失敗案例比較,看看有什麼不同。如果您對操作系統有偏見,那麼可以使用虛擬機在「更簡單」的平臺上進行測試。 –

+0

聽起來像你需要添加大量的跟蹤消息日誌記錄,並做一些困難的調試。你在使用SOAP + WSDL包裝嗎? –

+2

我建議你使用Wireshark等數據包嗅探器,或者將Indy自己的TIdLog ...組件中的一個附加到TIdHTTP,以查看實際的請求/響應數據實際上是什麼樣子,然後通過追蹤Indy的代碼來看看它將如何處理。 Indy的強大功能之一是能夠捕捉和回放原始數據以進行調試。您可以使用'TIdLogFile'或'TIdLogStream'來捕獲入站數據,然後附加一個'TIdIOHandlerStream'來播放它,而無需連接到真實服務器。 –

回答

2

RequestInfo.Params在構造函數中創建,並且在Destructor中有一個FreeAndNil(),所以一旦請求被釋放,Assigned()將在這個屬性上失敗。

鑑於此,並基於您的方案的混淆信息,我會假設您有一些線程問題,您在引用尚未刪除但Params屬性已存在的懸掛Request實例。有時候你很幸運,它有效,有時會吹AV。

或者,您手動在代碼中以某種方式刪除.Params屬性。也許你正在傳遞這個TStringList對象,而其他東西卻意外釋放它。直到請求完成之前,Indy纔會釋放這些內容。

總而言之,你是正確的,因爲你沒有提供足夠的信息,這個問題應該可能會被關閉。

+0

你與線程問題是正確的軌道。謝謝! :) – TobyD