close

⓪編著: 蕭沖

 

TServerSocket 與 TClientSocket 都算是一個包裝(Wrapper)物件的容器(container),也就是說它本身只是把Socket物件含入裡面,並透過介面來操作含在裡面的Socket物件。

真正有"作用"的Soket物件是TCustomWinSocket這個類別,注意裡面有「Win」這個字,若沒這個字,那就僅用Container,如上面講的TClientSocket。因此,在隨作各種事件與方法時,都是在處理TCustomWinSocket的子類別,如TServerWinSocket ,TServerClientWinSocket等。

當TServerSocket使用stNonBlocking模式時,其實就是選用了Windows Socket Mode 中的WSAAsyncSelect方式(可參考我之前的相關文章(http://aftcast.pixnet.net/blog/post/22191725)。簡單講就是用 Post Windows Message (FD_CONNECT、FD_CLOSE、FD_READ、FD_WRITE、FD_ACCEPT等事件)至Application的方式來處理,因此這時候負責收封包的OnClientRead的handler就算是Thread-safe的。相反的,若是stThreadBlocking模式,則於Accept時,會產生相對應的一個thread來處理與client端的連線,接著會去建立一個thread(你自己定的,參考下面),然後一切的存取都在thread裡,這時候就要注意Thread-safe的問題。必要時要用Critical Section、Synchronize等等。可參考我寫的關於Thread-safe的文章。

ClientRead事件中(僅stNonBlocking時才有用),因為是以message來觸發此事件,故常會有UI放大縮小或是動來動去時,造成封包收到的時候已經相連在一起。也就是說,比如你client端送packet1,然後packet2這二個封包。而你server上因為UI動來動去之類的,導致收到的時候buffer裡是packet1+packet2。還有一種情形也會,那就是你在這事件裡處理了一些很花時間的程式,這也是會造成收到封包是相連的。所以,stNonBlocking模式下,很重要的就是要自己去分離封包,千萬記得別以為你一定會「個別的收到」,常常會有數個一起收到喔!

當使用stThreadBlocking模式時,收封包的方式就不能使用ClientRead事件。要先自己去寫一個CLASS,繼承TServerClientThread。而一切的收與寫的實作都在這個自己寫的CLASS裡搞定。但要注意的是這個TServerClientThread的父類別雖然也是TThread,但不是在execute這個方法裡寫,而是在ClientExecute,我們必需override這個方法。help檔裡有範例。

TCustomWinSocket::Data的這個屬性很好用,它是一個void指標,我常會把它指向自己的一個struct,而這個struct當然是和這個socket有關的東西,比如說上面講的收到的封包(考慮會有相連封包的情形),最簡單的方式是就是用Ansistring來放封包串流。你會懷疑怎不用Byte[ ]? AnsiString我覺得最好用了,它放什麼都可以,但前題是要對AnsiString了解並有信心! 這struct也可以放一些user name,user id,user password等等。

⓪編著
arrow
arrow
    全站熱搜

    aftcast 發表在 痞客邦 留言(0) 人氣()