Delphi Indy和socket的一些區別


 

 

關於INDY--DELPHI的Internet控件集

Delphi 2010 中包含了大量的Indy控件,網上找點資料轉到博客下面給大家分享下。

你有沒有用DELPHI開發Internet程序?是不是常常會煩惱FastNet組件為什么沒有源代碼?有很多問題,不看源代碼,真不知道是什么問題。是不是也覺得FastNet組件支持的網絡協議還不夠多?現在不用煩惱了,有一套功能很豐富、使用很方便、開放源代碼的免費INTERNET控件集可以解決你的煩惱。這套控件集就是INDY了。

  什么是INDY?它有什么功能?怎么用?就讓我慢慢道來。

  INDY的全名是Internet Direct(也叫Winshoes),它是一套開放源代碼的Internet控件集,它支持大部分流行的Internet協議,包括TCP、UDP、DNS、ICMP、FINGER、FTP、GOPHER、HTTP、POP3、SMTP、TELNET、WHOIS等,支持BASE64、MD2、MD4、MD5等編解碼,提供INTERNET流行協議的客戶端和服務器控件。INDY控件集的客戶端和服務器控件都有完整、詳細的源代碼例程和幫助文件,用戶可以根據這些例子,簡單方便快速的建造各種服務器程序,例如WEB服務器、TELNET服務器、IRC服務器、TCP、UDP服務器等,而這些服務器都是支持多線程的。用戶也可以很簡單的編寫出各種客戶端程序,例如EMAIL、FINGER、FTP、PING、TELNET等。著名的OICQ使用的協議是UDP,有了INDY你可以使用UDP服務器和UDP客戶端寫出一個和OICQ較勁的東東來。

  INDY是完全基於SOCKET阻塞工作模式(后面討論)的開發庫,現在已經支持BORLAND DELPHI、C++ BUIDER和最新的Kylix(LINUX里的DELPHI)等開發平台。DELPHI 7.0將會把INDY作為它的INTERNET基本組件,由此可見INDY的強悍實力。

INDY提供的豐富例程就是絕好的教材。先編譯幾個例程,看看INDY的強大功能吧。要想熟練的使用好INDY,就得多多學習這些例程和參考幫助文件。


  熟悉WINSOCK編程的讀者一定會覺得奇怪吧,為什么INDY是是完全基於SOCKET阻塞工作模式的呢?異步模式(非阻塞模式)是WINSOCK的一大特點,為什么不用呢?
  其實,之所以大多數WINDOWS下的INTERNET程序都使用異步模式,這和WINSOCK的歷史有關。當WINSOCK被移植到WINDOWS的時候,當時的WINDOWS操作系統還是WINDOWS 3.1,而WINDOWS 3.1是不支持多線程的,不象UNIX下可以使用FORK來運行多進程。在WINDOWS 3.1下,如果使用阻塞模式,在通訊時會鎖定用戶界面使程序沒有響應,為了避免這種情況,WINSOCK就引入異步模式這個新特性。而使用異步模式來編制INTERNET程序也就成了WINDOWS程序員的經典教條。但是,隨着新的WINDOWS操作系統的出現,如WINDOWS 95、NT、98、ME、2000等,這些操作系統開始支持多線程。異步模式這個教條仍然深入人心,使很多程序員會下意識的拒絕使用阻塞模式。
  事實上,UNIX下的SOCKET只支持阻塞模式(現在UNXI的SOCKET有了一些新的非阻塞特性,不過絕大多數應用仍然使用阻塞模式)。阻塞模式具有以下幾個比異步模式優越的特點:
  編程更簡單,可以把所有處理SOCKET的代碼放在一起,順序執行,而不用分散在不同的事件處理代碼段里。
  更容易移植到UNIX,使用INDY的DELPHI程序,可以不做太多(甚至不做)修改,就可以把WINDOWS的DELPHI源代碼拿到LINUX下,用Kylix來編譯成LINUX下的網絡程序。 
更容易在多線程程序里使用,由於阻塞模式的代碼可以放在一起,可以很方便的把這些代碼包裹在線程里面來使用,而不象異步模式,需要針對不同的事件,設置不同的處理代碼。 

  為了兼顧簡單可靠和高效,INDY是基於阻塞模式工作的。阻塞模式需要等待任務完成才返回,這樣,當主線程里調用阻塞任務運行時,程序不能處理用戶界面的消息。INDY提供了一個控件TidAntiFreeze來解決這個問題。只要在你的程序里,簡單的填加一個TidAntiFreeze控件到任何地方(隨便往FORM上放),不需要寫任何代碼(最多把超時時間改一下),就可以很好的解決用戶界面不響應的問題。

  下面有兩段示范代碼,可以看出INDY控件的程序代碼和其他使用異步模式的Internet控件的程序代碼相比,是多么的簡潔:

代碼一:INDY控件的程序代碼(IndyClient代表INDY控件的一般形式)

with IndyClient do begin

Connect; 

Try

// 在這里寫入你的處理代碼

finally

Disconnect; 

end;

end;

代碼二:其他控件的程序代碼(SocketComponent代表一般的Internet控件) 

procedure TFormMain.TestOnClick(Sender: TComponent);

begin

with SocketComponent do begin

Connect; try

while not Connected do begin

if IsError then begin

Abort;

end;

Application.ProcessMessages;

OutData := 'Data To send';

while length(OutData) > 0 do begin

Application.ProcessMessages;

end;

finally Disconnect; end;

end;

end;

procedure TFormMain.OnConnectError;

begin

IsError := True;

end;

procedure TFormMain.OnRead;

var

i: Integer;

begin

i := SocketComponent.Send(OutData);

OutData := Copy(OutData, i + 1, MaxInt);

end;

關於INDY的簡單介紹就到這里了,感興趣的朋友就去下載一個用吧,你一定會喜歡上它的。

 

Indy 與 Socket的異同

 

1.

下面比較一下serverSokcet與clientSocket和idTcpServer與idTcpClient兩組通訊組件的異同:

socket即支持同部傳送數據又支持異步傳送數據。而idtcp則只支持同步傳送數據。

serverSokcet與clientSocket是非阻塞式的,基於事件觸發的。  


idTcpServer與idTcpClient是阻塞式的,基於多線程的。 

idTcpServer為每個連接的用戶建立一個單獨的線程,編程比較方便。

用indy作完成端口,經過壓力測試,發現可以承受600個並發用戶,當然這個與個人編程水平有關,做不好,100以上並發用戶都難接受

2.

問:一個網絡系統,在客戶端相互信息發送時,同時要求記錄保存到服務器的數據庫里,請教服務器端/客戶端分別用INDY的具體哪個控件比較合理?

答:IDTCPClient/IDTCPServer/IDUDPClient/IDUDPServer均可。 主要看具體應用要求

IDTCPClient/IDTCPServer會在運行時建立一個長時連接,直到退出;IDUDPClient/IDUDPServer則只管往指定的IP和端口發數據,能否收到由網絡來決定。它們消耗的資源也是有所區別。

3.

tcpclient tcpserver和 idtcpclient idtcpserver不是同一個控件,再D7中,
他們分屬在不同的模板(intenet,indy client,indy server),也有着不同的屬性、方法和事件。
另外,intenet的tcpserver在接收數據是自動建立線程觸發onAccept事件,因此必須要在此事件建立一個線程,可參考demo中的netchat例子。

1.阻塞模式編程建議用INDY的IDTCPCLIENT IDTCPSERVER
2.非阻塞模式建議用D7中可以通過 COMPONENT->INSTALL PACKAGES->add->DELPH7\BIN\DCLSOCKETS70.BPL來添加。
3。TCPCLIENT,TCPSERVER在D7中的DEMOS是用的阻塞模式,當客戶端連接后建立了線程來處理和客戶端的通訊問題。BLOCKMODE:=BMTHREADBLOCKING;
4。TCPCLIENT,TCPSERVER也可以工作在非阻塞模式,BLOCKMODE:=BMNOBLOCKING;這樣就象CLIENTSOCKET SERVERSOCKET了,但是TCPCLIENT 可以象CLIENTSOCKET一樣又ONREAD,ONWRITE,而TCPSERVER確沒有看到象SERVERSOCKET那樣的ONCLIENTREAD,ONCLIENTREAD.
5.查看TCPSERVER的源代碼,發現他和TCPCLIENT一樣最終是繼承於TBaseSocket的,那么應該也可以有ONREAD,ONWRITE。
6。如果我們象TCPCLIENT那樣作個procedure TcpServerReceive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer),你面寫處理代碼,然后TCPSERVER1.OnReceive:=TcpServerReceive; OnSend也如此類推,應該就可以了。
7。這個方法沒有測試,但原理是這樣的,只不過TCPSERVER的OnReceive,OnSend在設計時看不到而已,不等於他沒有


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM