基於Delphi的SocketIO模型全接觸
這與套接字模型非常相似。我以老陳的收信爲例來說明Socket I/O模型。
1.選擇型號
陳渴望看到女兒的來信。他每10分鍾下樓檢查一次郵箱,看看是否有他女兒的來信。這種情況下,“下樓查看郵箱”再上樓,耽誤了陳先生太多時間,其他工作都做不了。
選擇模型與陳老師的這種情況非常相似:反複檢查...如果有數據...接收/發送它。.......
使用線程進行選擇應該是一種常見的做法:
過程TListenThread。執行;
var
addr:TSockAddrIn;
FD _ read:tfd set;
time out:ttime val;
ASock,
main stock:t socket;
len,I:Integer;
begin
main stock:= socket(AF _ INET,SOCK_STREAM,IP proto _ TCP);
addr . sin _ family:= AF _ INET;
addr . sin _ port:= htons(5678);
addr.sin_addr。s _ addr:= htonl(in addr _ ANY);
bind(main stock,@addr,sizeof(addr));
聽(MainSock,5);
while(未終止)do
begin
FD _ ZERO(FD _ read);
FD _ SET(main stock,FD _ read);
time out . TV _ sec:= 0;
time out . TV _ usec:= 500;
if select (0,@ FD _ read,nil,nil,@ time out)> 0 Then//至少有一個連接
begin
if FD _ isset(main stock,FD _ read)Then
begin
for I:= 0 to FD _ read . FD _ count-1do//注意FD _ count begin
len:= sizeof(addr);
as ock:= accept(main stock,addr,len);
如果是無傚套接字,則
...//爲asock創建一個新線程,在新線程中選擇
end;
end;
end;
end;//while(不是self。已終止)
關機(MainSock,SD _ BOTH);
close socket(main stock);
end;
二:WSAAsyncSelect模型
後來陳先生用了微軟的新郵箱。這種郵箱很高級。一旦郵箱裡有新的信件,蓋茨就會給陳先生打電話:嘿,爺爺,你有新的信件!從此,陳先生再也不用頻繁的上下樓查看郵箱了,牙齒也不疼了。看看它,藍天...不,微軟。......
微軟提供的WSAAsyncSelect模型就是這個意思。
WSAAsyncSelect模型是Windows下最簡單易用的Socket I/O模型。使用這種模式時,Windows會以消息的形式通知應用程序網絡事件。
首先,定義一個消息標記常量:
const WM _ SOCKET = WM _ USER 55;
在主窗躰的私有域中再添加一個処理此消息的函數聲明:private
Procedure WM Socket(varmsg:t message);消息WM _ SOCKET
那麽你可以使用WSAAsyncSelect:var
addr:TSockAddr;
sock:t socket;
sock := socket( AF_INET,SOCK_STREAM,IP proto _ TCP);
addr . sin _ family:= AF _ INET;
addr . sin _ port:= htons(5678);
addr.sin_addr。s _ addr:= htonl(in addr _ ANY);
bind( m_sock,@addr,sizeof(SOCKADDR));
WSAAsyncSelect( m_sock,Handle,WM_SOCKET,FD_ACCEPT或FD _ CLOSE);
聽(m_sock,5);
......
應用程序可以分析接收到的WM_SOCKET消息,以確定哪個套接字生成了網絡事件和事件類型:ProcedureTFM Main。WM套接字(var msg:t message);
var
sock:TSocket;
addr:TSockAddrIn;
addrlen:Integer;
buf : Array [0..4095]的字符;
WParam of BEGIN
/MSG是生成網絡事件的套接字句柄,而LParam包含事件類型
CASE WSAGETSELECTEVENT(MSG . LParam)of
FD _ ACCEPT:
BEGIN
adren:
sock:= ACCEPT(MSG。WParam,addr,addrlen);
if sock INVALID _ SOCKET then
WSAAsyncSelect(sock,Handle,WM_SOCKET,FD_READ或FD_WRITE或FD _ CLOSE);
end;
FD_CLOSE : closesocket( Msg。WParam);
FD_READ : recv( Msg。WParam,buf[0],4096,0);
FD _ WRITE:;
end;
end;
0條評論