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

使用TClientSocket的問題

答題得分者是:aftcast
windheartalan
一般會員


發表:21
回覆:23
積分:8
註冊:2005-03-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-06-10 09:50:56 IP:60.248.xxx.xxx 訂閱
各位大大好,
小弟最近在使用TClientSocket時,發現了一個現象,
就是比方說我用sendtext分別於1秒,3秒,5秒送出了AAA,BBB,CCC三個字串給Server,

但會發現Server收到的時間,可能在第6秒,然後全部在一起回覆給我,
查詢Server端,確認Server端三個字串是幾乎同時收到的,也就是第1,2個字串看來似乎有在哪裡延遲到,

但client端,我也會於sendtext後寫log,看起來的確是1,3秒就送出了前兩筆,

後來利用sniffer之類的工具軟體去監控網路狀態,
發現我這邊真的是到6秒才將三筆一次送出,
感覺上是類似網卡,或是在os層,有被卡到,請問為何會如此,有大大碰過這樣的情形嗎?

大概找了一些討論文章,似乎跟socket層的sendbuffer有關,透過winsock的send method,
其實只會先丟到sendbuffer中,由os來控制送出,是這樣的嗎?
如果是如此,有辦法避掉或解決這個問題嗎? 如設定sendbuffer為0,或是不透過sendbuffer等...
還是說TClientSocket有別的send method可以避掉這個問題,請指導一下,感謝~

PS:TClientSocket是設成nonblocking

RootKit
資深會員


發表:16
回覆:358
積分:419
註冊:2008-01-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-06-10 22:45:37 IP:122.126.xxx.xxx 訂閱
我記得好像是...要再傳送內容結尾加上 #13#10 表示及時傳送。
否則好像是滿足或斷開時才傳。

上了年紀,記憶有點退化。
不太確定。.... 試試
windheartalan
一般會員


發表:21
回覆:23
積分:8
註冊:2005-03-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-06-22 15:59:31 IP:60.248.xxx.xxx 訂閱

這個我有加,好像不是這個原因.

===================引 用 RootKit 文 章===================
我記得好像是...要再傳送內容結尾加上 #13#10 表示及時傳送。
否則好像是滿足或斷開時才傳。

上了年紀,記憶有點退化。
不太確定。.... 試試
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-06-22 18:08:38 IP:210.64.xxx.xxx 訂閱
是windows的底層有防止小封包寄出的演算法造成。可以有二個解決辦法。
1) 用api把buffer size設成0
2) 禁用演算法

詳情要等這幾天有空時再把細節資料po上來… 近來太忙了!

ps。使用第一種方式不太好。

此外,一般來說除非是有即時性的應用(真的很即時喔),不然不建議去調整,這也是為何多數開發者不去理會這事。
若單純是資料連在一起而送的問題,一般的解決辦法是製定自己的協定。在資料的前,或後,或前與後加入一些額外的資料。那麼收到後就可以自行拆解…
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-06-23 01:38:52 IP:122.120.xxx.xxx 訂閱
再先簡單的補充一下:

>>其實只會先丟到sendbuffer中,由os來控制送出,是這樣的嗎?
是的,由AFD.SYS這個kernel mode driver接手,而它是依SO_SNDBUF這個值來做是否立即送的依據一之。就是我講的,你可以把它設定0,但不建議這樣。

此外,我說的演算法是Nagle algorithm,要了解的話google一下…
重點是: 可以把socket 的option中的一項叫TCP_NODELAY 設定起來。這樣就不會使用那個演算法了。

以上所述都是以win32 api的方法,vcl上沒有對應的方式。所以… 要使用vcl 中的socket handle來當參數,使用WIN32 API改變原來的行為。



------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
windheartalan
一般會員


發表:21
回覆:23
積分:8
註冊:2005-03-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-06-23 14:09:22 IP:60.248.xxx.xxx 訂閱
制定自己的協定 ,收到後自行拆解這個部份是有做的,
只是如大大所說,因為要求的是很即時的話,這時就會看的出有些微的秒差,

===================引 用 aftcast 文 章===================
是windows的底層有防止小封包寄出的演算法造成。可以有二個解決辦法。
1) 用api把buffer size設成0
2) 禁用演算法

詳情要等這幾天有空時再把細節資料po上來… 近來太忙了!

ps。使用第一種方式不太好。

此外,一般來說除非是有即時性的應用(真的很即時喔),不然不建議去調整,這也是為何多數開發者不去理會這事。
若單純是資料連在一起而送的問題,一般的解決辦法是製定自己的協定。在資料的前,或後,或前與後加入一些額外的資料。那麼收到後就可以自行拆解…
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-06-23 14:14:37 IP:118.169.xxx.xxx 訂閱
期待中 ^_^

===================引 用 aftcast 文 章===================
詳情要等這幾天有空時再把細節資料po上來… 近來太忙了!

windheartalan
一般會員


發表:21
回覆:23
積分:8
註冊:2005-03-24

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-06-23 14:45:43 IP:211.75.xxx.xxx 訂閱
謝謝大大的補充~

有去google了一下,看起來這方向應該是可以解決問題,
大大所說的要用win32 api,意思上我是理解,也查的到大概是要用哪個api(setsockopt 是嗎?)
另外設定TCP_NODELAY 這個時機是? 因為小弟使用的是TClientSocket,
那是connect起來後去設定,還是還沒連線就可以設定了呢?

請多指教,感謝.

===================引 用 aftcast 文 章===================
再先簡單的補充一下:

>>其實只會先丟到sendbuffer中,由os來控制送出,是這樣的嗎?
是的,由AFD.SYS這個kernel mode driver接手,而它是依SO_SNDBUF這個值來做是否立即送的依據一之。就是我講的,你可以把它設定0,但不建議這樣。

此外,我說的演算法是Nagle algorithm,要了解的話google一下…
重點是: 可以把socket 的option中的一項叫TCP_NODELAY 設定起來。這樣就不會使用那個演算法了。

以上所述都是以win32 api的方法,vcl上沒有對應的方式。所以… 要使用vcl 中的socket handle來當參數,使用WIN32 API改變原來的行為。



系統時間:2024-04-27 6:01:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!