Delphi編寫事件模型客戶端 3

2021-09-05 03:12:28 字數 3365 閱讀 9768

工作者執行緒是傳送和接收資料的主要部分。沒有這部分**,是無法實現網路通訊的。今天我就來講一下我寫的工作者執行緒是如何實現的。

首先是工作者執行緒的建立和銷毀。

constructor tworkthread.create(parent: tioevents);

begin

inherited create(false);

fparent:=parent;

end;

我寫工作者執行緒的時候,是將父類(

tioevents

)通過引數傳遞進來,這樣寫是為了以後的使用方便。

destructor tworkthread.destroy;

begin

inherited;

end;

以下是工作者執行緒的主要**。

procedure tworkthread.execute;

varindex:integer;

ne:twsanetworkevents;

begin

while not terminated do

begin

index := wsawaitformultipleevents(fparent.feventnums,@fparent.feventarray[0],false,wsa_infinite,false);

if index = -1 then

begin

//得到-1

應該是需要斷開

exit;

end;

//得到事件對應的陣列下標

index := index - wsa_wait_event_0;

//重置事件

wsaresetevent(fparent.feventarray[index]);

if (index = wsa_wait_failed) or (index = wsa_wait_timeout) or (index = wsa_invalid_parameter) or (wsa_invalid_handle = index) or (wsanotinitialised = index) then

begin

continue;

end;

//開始得到網路事件

if wsaenumnetworkevents(fparent.fsocketarray[index],fparent.feventarray[index],@ne) <> invalid_socket then

begin

case ne.lnetworkevents of

fd_read:  socketread;   //

接收資料

fd_write: socketwrite;  //

傳送資料

fd_close: socketclose;  //

連線關閉

end;

end;

end;

end;

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

由於我在函式

wsawaitformultipleevents

中使用了引數

wsa_infinite

,這樣程式會等在這裡一直到套接字上有事件觸發。事件觸發以後我使用函式

wsaresetevent

重置了事件。並使用函式

wsaenumnetworkevents

確定出觸發了什麼事件。根據不同的事件我呼叫不同的處理方法。

對於連線關閉事件我的實現是:

procedure tworkthread.socketclose;

begin

if assigned(fparent.fondisconnect) then

begin

fparent.ondisconnect;

end;

//服務端斷開

fparent.clearbuffer;

destroy;

end;

對於接收到資料事件,我的實現是:

procedure tworkthread.socketread;

varbytestransferred,dwflags: dword;

idata:pchar;

begin

bytestransferred:=0;

fparent.postrecv;

begin

if bytestransferred = 0 then

begin

exit;

end;

fparent.frecviodata.bufferlen:=bytestransferred;

getmem(idata,fparent.frecviodata.bufferlen);

strmove(idata,@fparent.frecviodata.buffer,fparent.frecviodata.bufferlen);

if assigned(fparent.fonrecive) then

begin

fparent.fonrecive(idata,fparent.frecviodata.bufferlen);

end;

freemem(idata);

end;

end;

我呼叫函式

用來得到接收到的資料資訊。並產生乙個接收資料事件。

對於傳送資料事件,我的處理方法是:

procedure tworkthread.socketwrite;

begin

dec(fparent.ftotalcount);

if assigned(fparent.ffirstnode) then

begin

if not fparent.postsend then

begin

closesocket(fparent.fsocket);

end;

endelse

begin

fparent.fsending:=false;

end;

end;

繼續投遞乙個

postsend

。來繼續傳送,傳送佇列中的資料。至此,

event

模型編寫客戶端通訊的主要**就已經全部寫完了,我的**一定會有一些問題,希望大家看了以後能指出錯誤來,好讓大家一起進步。

initialization

begin

wsastatupsocket;

end;

finalization

begin

wsacleanupsocket;

end;

end.

Python編寫FTP客戶端

之前寫過一篇ftp服務端的文章,這篇介紹一下客戶端吧。在使用虛擬機器的時候,由於虛擬機器工具沒安裝成功,所以我決定用ftp在主機與虛擬機器之間傳送檔案,在虛擬機器上開啟ftp服務,然後把客戶端放在主機上,當然也可以顛倒過來。服務端請參考 python實現ftp伺服器 import ftplib im...

瘦客戶端 胖客戶端 智慧型客戶端

胖客戶端模式將應用程式處理分成了兩部分 由使用者的桌面計算機執行的處理和最適合乙個集中的伺服器執行的處理。乙個典型的胖客戶端包含乙個或多個在使用者的pc上執行的應用程式,使用者可以檢視並運算元據 處理一些或所有的業務規則 同時提供乙個豐富的使用者介面做出響應。伺服器負責管理對資料的訪問並負責執行一些...

關於客戶端編寫的問題

最近在敲大話設計模式中的c 我是在看uml圖去敲 的.由於uml圖中沒有畫出客戶端的圖.導致寫客戶端的 時,很是費力.不清楚該怎麼寫.沒有一點的章法.總是蒙幾句.最後執行出來了,感覺就是 對的,也不知道自己是怎麼寫出來的.讓我從頭寫一次.和上次的感覺還是一樣的.我仔細分析了一下.關於為什麼不會寫客戶...