亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        基于Delphi的SocketI/O模型全接觸

        字號:

        這和Socket模型非常類似。下面我就以老陳接收信件為例講解Socket I/O模型。
            一:select模型
            老陳非常想看到女兒的信。以至于他每隔10分鐘就下樓檢查信箱,看是否有女兒的信,在這種情況下,“下樓檢查信箱”然后回到樓上耽誤了老陳太多的時間,以至于老陳無法做其他工作。
            select模型和老陳的這種情況非常相似:周而復(fù)始地去檢查......如果有數(shù)據(jù)......接收/發(fā)送.......
            使用線程來select應(yīng)該是通用的做法:
            procedure TListenThread.Execute;
            var
            addr : TSockAddrIn;
            fd_read : TFDSet;
            timeout : TTimeVal;
            ASock,
            MainSock : TSocket;
            len, i : Integer;
            begin
            MainSock := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
            addr.sin_family := AF_INET;
            addr.sin_port := htons(5678);
            addr.sin_addr.S_addr := htonl(INADDR_ANY);
            bind( MainSock, @addr, sizeof(addr) );
            listen( MainSock, 5 );
            while (not Terminated) do
            begin
            FD_ZERO( fd_read );
            FD_SET( MainSock, fd_read );
            timeout.tv_sec := 0;
            timeout.tv_usec := 500;
            if select( 0, @fd_read, nil, nil, @timeout ) > 0 then //至少有1個等待Accept的connection
            begin
            if FD_ISSET( MainSock, fd_read ) then
            begin
            for i:=0 to fd_read.fd_count-1 do //注意,fd_count <= 64,也就是說select只能同時管理最多64個連接
            begin
             len := sizeof(addr);
             ASock := accept( MainSock, addr, len );
             if ASock <> INVALID_SOCKET then
            ....//為ASock創(chuàng)建一個新的線程,在新的線程中再不停地select
             end;
            end;   
            end;
            end; //while (not self.Terminated)
            shutdown( MainSock, SD_BOTH );
            closesocket( MainSock );
            end;
            二:WSAAsyncSelect模型
            后來,老陳使用了微軟公司的新式信箱。這種信箱非常先進,一旦信箱里有新的信件,蓋茨就會給老陳打電話:喂,大爺,你有新的信件了!從此,老陳再也不必頻繁上下樓檢查信箱了,牙也不疼了,你瞅準(zhǔn)了,藍(lán)天......不是,微軟......
            微軟提供的WSAAsyncSelect模型就是這個意思。
            WSAAsyncSelect模型是Windows下最簡單易用的一種Socket I/O模型。使用這種模型時,Windows會把網(wǎng)絡(luò)事件以消息的形勢通知應(yīng)用程序。
            首先定義一個消息標(biāo)示常量:
            const WM_SOCKET = WM_USER + 55;
            再在主Form的private域添加一個處理此消息的函數(shù)聲明: private
            procedure WMSocket(var Msg: TMessage); message WM_SOCKET;
            然后就可以使用WSAAsyncSelect了: var
            addr : TSockAddr;
            sock : TSocket;
            sock := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
            addr.sin_family := AF_INET;
            addr.sin_port := htons(5678);
            addr.sin_addr.S_addr := htonl(INADDR_ANY);
            bind( m_sock, @addr, sizeof(SOCKADDR) );
            WSAAsyncSelect( m_sock, Handle, WM_SOCKET, FD_ACCEPT or FD_CLOSE );
            listen( m_sock, 5 );
            ....
            應(yīng)用程序可以對收到WM_SOCKET消息進行分析,判斷是哪一個socket產(chǎn)生了網(wǎng)絡(luò)事件以及事件類型: procedure TfmMain.WMSocket(var Msg: TMessage);
            var
            sock : TSocket;
            addr : TSockAddrIn;
            addrlen : Integer;
            buf : Array [0..4095] of Char;
            begin
            //Msg的WParam是產(chǎn)生了網(wǎng)絡(luò)事件的socket句柄,LParam則包含了事件類型
            case WSAGetSelectEvent( Msg.LParam ) of
            FD_ACCEPT :
            begin
            addrlen := sizeof(addr);
            sock := accept( Msg.WParam, addr, addrlen );
            if sock <> INVALID_SOCKET then
             WSAAsyncSelect( sock, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE );
            end;
            FD_CLOSE : closesocket( Msg.WParam );
            FD_READ : recv( Msg.WParam, buf[0], 4096, 0 );
            FD_WRITE : ;
            end;
            end;