線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2635
推到 Plurk!
推到 Facebook!

关于TIdTCPServer接收数据的疑问

尚未結案
fangwy
中階會員


發表:99
回覆:139
積分:62
註冊:2003-09-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-02 10:37:39 IP:218.5.xxx.xxx 未訂閱
在使用TIdTCPServer,我用下面的语句读收到的数据: TIdPeerThread(List.Items[List.Count - 1]).Connection.ReadBuffer(buffResult, ResultLength); 但发现ReadBuffer只有读满ResultLength指定长度的数据才返回,否则就阻塞住不返回.我试图找到获取读缓冲区数据长度的方法,但TIdTCPServer好象没提供. 我又采取设置超时的方法去循环读写,但问题又来了,因ReadBuffer没有返回实际读的长度,无法确定是否读到数据及读了多少,而且超时返回就引发异常,终止执行,不好控制. 哪位大大熟悉TIdTCPServer,给我一个解决的方法,谢谢.
cxg
中階會員


發表:116
回覆:192
積分:76
註冊:2004-02-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-08-02 13:05:59 IP:222.35.xxx.xxx 未訂閱
你用 ReadLn 试试: procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var S : String; begin S := AThread.Connection.ReadLn(#$A, 100); memo1.lines.add( S); end; 發表人 - cxg 於 2005/08/02 13:07:05
fangwy
中階會員


發表:99
回覆:139
積分:62
註冊:2003-09-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-08-02 13:37:06 IP:218.5.xxx.xxx 未訂閱
谢谢cxg,我读的可能不是一个字符串,可能是经过压缩后的数据或如#1#2这样无法显示的字节.用ReadLn可能不行.
cxg
中階會員


發表:116
回覆:192
積分:76
註冊:2004-02-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-08-02 13:49:22 IP:222.35.xxx.xxx 未訂閱
我试过是没有问题的,可以接受到的。
fangwy
中階會員


發表:99
回覆:139
積分:62
註冊:2003-09-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-08-02 15:33:47 IP:218.5.xxx.xxx 未訂閱
遇到#0也没问题吗?我处理的数据中#0可能是有效数据而不是结束符. 你的方法晚上我会试试,现在正做其他工作. 發表人 - fangwy 於 2005/08/02 15:34:50
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-08-02 23:49:45 IP:61.219.xxx.xxx 未訂閱
這樣試試看 iLen:=IdTcpConnect.ReadFromStack(false, 20, false); if iLen>0 then IdTcpConnect.ReadBuffer(Buffer,iLen); ReadFromStack 會從 Socket 的 Buffer 中搬資料到 Indy 內建的 Buffer, 並傳回搬了多少長度的資料過去, 再由 ReadBuffer 將其讀回就可以了.
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-08-02 23:56:07 IP:61.219.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?topic_id=66366 找到這篇最後一段程式碼可以參考一下
fangwy
中階會員


發表:99
回覆:139
積分:62
註冊:2003-09-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-08-03 09:09:35 IP:218.5.xxx.xxx 未訂閱
引言: 這樣試試看 iLen:=IdTcpConnect.ReadFromStack(false, 20, false); if iLen>0 then IdTcpConnect.ReadBuffer(Buffer,iLen); ReadFromStack 會從 Socket 的 Buffer 中搬資料到 Indy 內建的 Buffer, 並傳回搬了多少長度的資料過去, 再由 ReadBuffer 將其讀回就可以了.
有一个问题,难道数据没有自动被搬到Indy内建的Buffer中吗?
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-08-03 09:39:26 IP:203.69.xxx.xxx 未訂閱
由原始碼來看, 是沒有自動搬 而是用ㄧ個無限迴圈 等到讀到足夠資料.... Indy 是 open source 好處就是有疑問可以自己找出根源...    IdTCPConnection.pas
procedure TIdTCPConnection.ReadBuffer(var ABuffer; const AByteCount: Integer);
begin
  if (AByteCount > 0) and (@ABuffer <> nil) then begin
    // Read from stack until we have enough data
    while (InputBuffer.Size < AByteCount) do begin
      ReadFromStack;
      CheckForDisconnect(True, True);
    end;
    // Copy it to the callers buffer
    Move(InputBuffer.Memory^, ABuffer, AByteCount);
    // Remove used data from buffer
    InputBuffer.Remove(AByteCount);
  end;
end;
fangwy
中階會員


發表:99
回覆:139
積分:62
註冊:2003-09-10

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-08-03 17:26:58 IP:218.5.xxx.xxx 未訂閱
谢谢malanlk,我的两个问题都得到的圆满的解决. 之前我也想了一个方法基本解决了所遇到的问题.但需要设置超时以防读不到要求的字节数时就无法返回. malanlk的方法省掉了这个麻烦.
系統時間:2024-07-01 3:01:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!