2014-02-21 38 views
2

我是Delphi XE5的新手,主要與VB.Net和一些Java一起工作。我試圖從傳入的TCP連接中讀取未知數量的字節,並且沒有任何運氣研究如何確定要讀取的輸入緩衝區中有多少個字節。看來,我嘗試的每種方法,即ReadBytes,ReadStream等都要求我明確告訴他們要讀取多少個字節或它們是否被阻塞。我只需要一種方法來確定輸入緩衝區中有多少個字節,以便我可以使用ReadBytes來讀取它們。Delphi IOHandler讀取未知的字節數

begin 
    Client.IOHandler.CheckForDataOnSource(300); 
    if Not Client.IOHandler.InputBufferIsEmpty then 
    Client.IOHandler.ReadBytes(rxBuf); 
end; 

爲了不阻止我需要提供輸入緩衝區中的字節數,但我不能確定如何做到這一點。我嘗試了InputBuffer.Size,但是返回的數字比可能存在的數字大得多。

現在我已經試過如下:

begin 
    if Client.IOHandler.InputBufferIsEmpty then 
    begin 
    Client.IOHandler.CheckForDataOnSource(1000); 
    if Not Client.IOHandler.InputBufferIsEmpty then 
    begin 
     Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
    end; 
    end 
    else 
    Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
end; 

當我把一個斷點,單步執行代碼,代碼跳過ExtractToBytes和RXBUF仍然爲零,即使有在輸入緩衝區中的數據。爲什麼?

我遺漏了一些代碼之前。這是整個事情。

while stop-start <MainForm.Timeout do 
begin 
    if Client.IOHandler.InputBufferIsEmpty then 
    begin 
    Client.IOHandler.CheckForDataOnSource(1000); 
    stop := Ticks; 
    if Not Client.IOHandler.InputBufferIsEmpty then 
    begin 
     Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
     break; 
    end; 
    end 
    else 
    Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
    break; 
end; 

我知道緩衝區中存在數據,因爲通過代碼進入break;但ExtractToBytes(rxBuf)未被評估,並且不知道爲什麼。

回答

3

InputBuffer.Size是物理上在InputBuffer內存中的實際字節數。它不能比實際存儲的大。 InputBufferIsEmpty()只需返回是否InputBuffer.Size > 0

begin 
    if Client.IOHandler.InputBufferIsEmpty then 
    begin 
    Client.IOHandler.CheckForDataOnSource(1000); 
    Client.IOHandler.CheckForDisconnect; 
    if Client.IOHandler.InputBufferIsEmpty then Exit; 
    end; 
    Client.IOHandler.ReadBytes(rxBuf, Client.IOHandler.InputBuffer.Size); 
end; 

或者,使用InputBuffer.ExtractToBytes()無條件提取目前無論是在InputBuffer,即使它正好是空的:

begin 
    if Client.IOHandler.InputBufferIsEmpty then 
    begin 
    Client.IOHandler.CheckForDataOnSource(1000); 
    Client.IOHandler.CheckForDisconnect; 
    if Client.IOHandler.InputBufferIsEmpty then Exit; 
    end; 
    Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
end; 

或者,您也可以通過-1ReadBytes(),告訴它返回無論目前在InputBuffer(它將首先呼叫IOHandler.ReadFromSource()填充InputBuffer,然後再提取之前):

begin 
    Client.IOHandler.ReadBytes(rxBuf, -1, False); 
end; 

更新:無論是否讀取任何內容,您的循環呼叫break。這是你真正想要的嗎?如果沒有,那麼你需要最後break移動到begin/end塊,使得它僅被評估,如果ExtractToBytes()被稱爲:

while GetTickDiff(start, Ticks) < MainForm.Timeout do 
begin 
    if Client.IOHandler.InputBufferIsEmpty then 
    begin 
    Client.IOHandler.CheckForDataOnSource(1000); 
    if Not Client.IOHandler.InputBufferIsEmpty then 
    begin 
     Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
     break; 
    end; 
    end 
    else 
    begin 
    Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
    break; 
    end; 
end; 

在這種情況下,你就可以簡化循環了一下:

start := Ticks; 
while Client.IOHandler.InputBufferIsEmpty do 
begin 
    if GetTickDiff(start, Ticks) >= MainForm.Timeout then Break; 
    Client.IOHandler.CheckForDataOnSource(1000); 
end; 
Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 

在這種情況下,你可以只得到完全擺脫循環的,只是利用印自己的超時代替:

Client.IOHandler.CheckForDataOnSource(MainForm.Timeout); 
Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 

或者:

Client.IOHandler.ReadTimeout := MainForm.Timeout; 
Client.IOHandler.ReadBytes(rxBuf, -1, False); 
+0

請參閱我上面的修改。感謝您的評論。 – user1549123

0

謝謝。我不明白的是,爲什麼如果輸入緩衝區中有數據不會評估ExtractBytes?這是我試圖實施的邏輯。我使用串口設備通過TCP進行通信。我給它發送一個可以打開通信的角色,並且它會回覆一些可能會有所不同的信息。

// Stay in loop until a certain amount of time has passed with no data 
// I understand I can use the timeout as well 
while GetTickDiff(start, Ticks) < MainForm.Timeout do 
    begin 
    if Client.IOHandler.InputBufferIsEmpty then 
     begin 
     Client.IOHandler.CheckForDataOnSource(1000); 
     if Not Client.IOHandler.InputBufferIsEmpty then 
      begin 
      // If there is data in the buffer get it 
      // But why is ExtractToBytes not evaluated 
      Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
      // I break the loop because I am assuming ExtractToBytes has been evaluated 
      break; 
      end; 
     end 
    else 
     begin 
     Client.IOHandler.InputBuffer.ExtractToBytes(rxBuf); 
     break; 
    end; 

end;

我明顯誤解的是,僅僅因爲輸入緩衝區中有數據,ExtractToBytes不一定會被評估。感謝您的意見,我會多花一點時間。