全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2011
推到 Plurk!
推到 Facebook!

DirectPlay SDK中文翻譯Understanding DirectPlay

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-11-27 18:12:20 IP:61.218.xxx.xxx 未訂閱
DirectPlay SDK中文翻譯Understanding DirectPlay(1)      Understanding DirectPlay(1) 作者:楊冰(源代碼之光) E-mail:iceryeah2000@163.com 創建時間:2002-9-26 最後修改時間:2002-10-6 備注:在Understanding DirectPlay章節中包括許多技術細節,為了達到清晰的翻譯,有些句子我沒有直接按原文翻譯。而是經過自己的理解,潤色,意譯而成,有些句子更像一般教程裡的話。另外,我沒有翻譯其中的Peer-to-Peer Sessions和Understanding DirectPlay Voice,因為,大家用這兩部分的技術很少,並且技術還是相對簡單的。    Understanding DirectPlay(1) (這裡是Understanding DirectPlay第一部分,翻譯的是Client/Server Sessions章節。)    這部分講述DirectPlay背景知識。使你理解如何在遊戲中使用DirectPlay API。    Client/Server Sessions 客戶/服務會話由一組角色(Player,我把它翻譯成角色,是因為一個用戶賬號可以對應多個角色),或一組客戶端,連接中央服務器而成。DirectPlay有一個麻煩的事情:在客戶/服務模式下,一個客戶端不知道另外其它客戶端的狀態,隻有服務器知道。當消息需要在兩個單獨的客戶端之間傳送消息,麻煩就出現了,因為DirectPlay沒有提供直接客戶對客戶這樣的消息傳送方式。所以需要客戶/服務會話來解決。    一個客戶/服務會話分為兩個部分: 1 服務端程序運行在遠程電腦上。服務器的基本功能是一個中央消息輪,以及遊戲主機。服務器必須接收和管理所有從客戶端發送的消息,並且發送處理後的消息以進行恰當的回應。任何從一個客戶端傳送到另一個客戶端的數據,都必須依靠服務器進行傳送。 2 一個客戶端程序,它運行在玩家的電腦上。此程序最主要的功能是管理UI(用戶界面),並且保持遊戲狀態和服務器同步。    有某些部分隻是被其中一個部分所負責。比如,玩家的圖形引擎必須要由客戶端程序完成。不過,處理過程的大多數方面,都需要兩方面共同完成。編寫一個高效的客戶/服務類型遊戲需要注意如何對客戶/服務這兩部分進行分工。    這部分文檔描述客戶/服務遊戲的基本原理:    Initiating a Client/Server Session 一個客戶/服務遊戲能通過大廳進行連接,或者直接的通過服務端進行連接。    服務端程序 客戶/服務遊戲通常被大廳安排進程。連接服務端程序由兩種方法,第一種方法(建議使用)就是使遊戲擁有支持大廳功能,這樣就可以直接連接到服務端。這種方法的優點是能讓服務端和大廳可以在一個會話中進行通訊。 服務端也可以直接被客戶端連接,自己進行廣播,等待客戶端加入。這部分在Selecting a Client/Server Host(選擇一個客戶/服務主機)有細節描述。    當服務端程序被運行,它必須調用IDirectPlay8Server::Initialize進行初始化。和DirectPlay其它初始化函數一樣,這個函數的主要目的是提供一個DirectPlay指針,指向回調消息句柄(callback message handler)。然後調用IDirectPlay8Server::SetServerInfo描述當前遊戲。客戶端直到這個函數被調用才能夠連接服務端。    客戶端程序 首先你必須決定你的遊戲是否是在大廳裡進行和服務端連接的。如果是那樣的話,創建和初始化一個支持大廳程序對象(CLSID_DirectPlay8LobbiedApplication)。這樣,你就可以通過對象指針來指向你的消息。消息處理機從支持大廳程序的對象處接收消息,也就是間接的接收大廳客戶端和大廳的消息。    1 如果是支持大廳連接的話,IDirectPlay8LobbiedApplication::Initialize返回一個連接大廳客戶端的句柄,並且DPL_MSGID_CONNECT消息從支持大廳程序消息處理器發送。PdplConnectionSettings連接的結構指針指向DPL_CONNECTION_SETTINGS結構,這個結構裡面包含地址對象。 2 如果程序不是通過大廳進行連接,則你既不接收連接句柄,也不接收消息。不過,如果你調用IDirectPlay8LobbiedApplication::SetAppAvailable,一個大廳客戶端會稍後連接你的運行程序到一個會話中,並發送DPL_MSGID_CONNECT消息。    你應該創建和初始化一個客戶對象(CLSID_DirectPlay8Client)。這個對象是你進行通訊的主要工具。如果你想有一個多人角色在會話中,你必須為每一個角色創建一個獨立的實例對象給它們。    Selecting a Service Provider for a Client 所謂的服務提供就是你的網絡連接協議。大多數遊戲使用TCP/IP或者Modem協議,不過DirectPlay還提供了serial和IPX兩種支持。 如果你的用戶用大廳客戶端聯入了一個會話,你可以通過檢驗DPL_CONNECTION_SETTINGS來決定所要使用的網絡協議,即服務提供,這個結構是伴隨DPL_MSGID_CONNECT消息的。你或者可以詢問用戶來決定使用什麼樣的協議。通過客戶對象中的IDirectPlay8Client::EnumServiceProviders函數來枚舉當前可用的網絡協議。在Using DirectPlay Enumerations有詳細介紹。 一旦你選擇了一個協議,你要創建一個DirectPlay地址對象給你的用戶(一個設備地址)。你可以用這個地址通過一系列的數字(從DirectPlay函數中獲得)來定義你的設備。在DirectPlay Addressing有詳細對DirectPlay地址和地址對象的討論。    Selecting a Client/Server Host 根據定義,服務端程序主持會話。要加入到會話中,客戶端程序必須獲得服務器主機的地址。通用的檢取主機的方法是通過大廳服務器。這樣,當一個用戶連接到會話,你接收到的連接信息DPL_MSGID_CONNECT將包括主機的地址。結構中pdp8HostAddress成員有指向主機地址的指針。 如果服務端使用IP/IPX網絡協議,也可以創建一個廣播會話(broadcast session),在局域網中。創建廣播會話,可以調用IDirectPlay8Server::SetServerInfo。然後調用IDirectPlay8Server::Host來發布主持會話的主機。你可以通過IDirectPlay8Server::Host函數的pdnAppDesc 參數更改DPN_APPLICATION_DESC結構,以獲得更詳細的配置信息。    你可以讓你的用戶查找可用的主機或者會話。可以在客戶端程序上使用IDirectPlay8Client::EnumHosts來獲得此項功能。一旦用戶選擇了一個主機,你就可以請求連接了。    Connecting to a Client/Server Session 所有的客戶端必須加入所聯入主機的會話中,即使這個會話是通過大廳來管理的(當客戶聯入主機中,就必須聯入會話,否則,服務器就曝光了:)楊冰注)。一個連接把客戶端看成一個會話成員,並且提供主機與客戶端聯系的信息。主機有權同意或否決接收一個連接請求。 服務端程序    當一個客戶端試圖加入一個會話,主機接收到DPN_MSGID_INDICATE_CONNECT消息。如果同意此客戶端加入,返回S_OK,不同意則返回其它任意值。客戶端將接收DPN_MSGID_CONNECT_COMPLETE消息,這裡包含服務端程序對它的回復。你可以在這個時候定義角色信息索引(player context value)(字面上,沒有索引的意思,但它實際提供了一個索引功能。楊冰注),或者等到你接收到DPN_MSGID_CREATE_PLAYER消息。在Using Player Context Values章節中進一步的詳細介紹。    如果角色成功的加入會話中,所有的客戶端和服務端將接收到DPN_MSGID_CREATE_PLAYER消息以及角色ID(DPNID)。如果你想定義一個角色信息索引,並且現在還沒有做,你在此消息回應前必須定義好,否則,你將不再擁有更改此項的權力。 客戶端程序    為了連接到會話,你必須取得會話主機的地址。如果你的遊戲是通過大廳客戶端連接的,你可以通過IDirectPlay8LobbiedApplication::GetConnectionSettings.來獲得主機的地址。 如果你沒有會話主機的地址並且你使用IP或者IPX網絡協議,你可以通過IDirectPlay8Client::EnumHosts在廣播會話中尋找可用的主機。你可以通過枚舉可用的主機來取得地址。DPN_APPLICATION_DESC描述關聯的會話。    為了加入會話,調用IDirectPlay8Client::SetClientInfo來設定角色名稱(name),然後調用IDirectPlay8Client::Connect以及獲得得主機地址來連接會話。 你將會接收到DPN_MSGID_CONNECT_COMPLETE消息回應。如果主機同意這次連接,hResultCode成員會被設置為S_OK。如果不是,hResultCode將被設定為DPNERR_HOSTREJECTEDCONNECTION。    Managing a Client/Server Session 作為主機,服務端負責管理會話。它含有以下幾個基本工作方面: 1 管理會話成員列表和他們的網絡地址。DirectPlay已經做好了這個任務,但是服務端程序還要提供管理用戶數據的功能。 2 判斷一個新用戶是否可以加入到會話中。 3 為新用戶提供當前的遊戲狀態。    當一個用戶試圖加入會話,主機將接收到DPN_MSGID_INDICATE_CONNECT消息。如果接收這個用戶,則返回S_OK。返回其它值則表示不同意。用戶則接收消息DPN_MSGID_CONNECT_COMPLETE,其中包含主機發送給它的返回值(S_OK或者其他)。 主機可以調用IDirectPlay8Server::DestroyClient.把用戶移出會話。    Normal Client/Server Game Play 在DirectPlay中,消息本質上是一些從客戶端發送到服務器或連接程序(vice versa,通過提供的功能翻譯)的遊戲數據。DirectPlay沒有具體的規定這些數據塊的結構或內容,它隻是僅僅提供了傳遞機制。一旦遊戲開始運行,每個客戶端將從服務端或連接程序接收有關遊戲的消息數據流。這些消息的傳遞,就是為了讓各個客戶端狀態達到同步,以便每個用戶都看到相同的UI(用戶界面)。    對於大多數遊戲,尤其是那些狀態更新迅速的遊戲,你要更加小心的管理你的消息。DirectPlay消息發送級別管理裝制(throttles outgoing messages)可以依據發送的消息級別而管理發送各個消息的先後順序。現在你隻要依據各個消息的主要性,來安排發送級別就行了。在Basic Networking章節中有詳細討論。(此段多為意譯。冰注)    服務端程序: 調用IDirectPlay8Server::SendTo,發送消息給客戶端。然後客戶端會接收到消息DPN_MSGID_RECEIVE。    客戶端程序 調用IDirectPlay8Client::Send,發送消息給服務端。服務端將會接收到DPN_MSGID_RECEIVE消息。    備注:DirectPlay沒有提供客戶端之間進行通訊的機制。任何客戶端之間要進行通訊,必須要通過服務端程序。    使用組(Groups) 很多遊戲允許角色加入一個組裡。比如,一個以班(squad-based)或者說是分組的遊戲,每個角色都是一個組成員。DirectPlay允許服務端為角色創建組。如果你的遊戲裡設定的組與DirectPlay提供的組差不多,完全可以使用DirectPlay為你提供的設置。DirectPlay組在本質上是為了簡化消息管理。當你定義了一個組,你就可以用一條IDirectPlay8Server::SendTo來給組裡的每個角色發送消息。    調用IDirectPlay8Server::CreateGroup.來創建一個組。你的消息管理器隨後回接收到DPN_MSGID_CREATE_GROUP消息。這個消息其中包括組的ID(用來作為發送的識標)。一旦組建立起來,你就可以用IDirectPlay8Server::AddPlayerToGroup.來添加角色。    當你的組完全建立好後(角色已經被加入等),你就可以調用IDirectPlay8Server::SendTo來給組發送消息,其中dpnid參數被設為組的ID。所有的組成員將會接收到消息DPN_MSGID_RECEIVE。 可以調用IDirectPlay8Server::RemovePlayerFromGroup.來移除角色。最後,銷毀組調用IDirectPlay8Server::DestroyGroup。    Leaving a Client/Server Session 客戶端可以調用IDirectPlay8Client::Close.來離開會話。服務器將被消息DPN_MSGID_DESTROY_PLAYER通知。    Terminating a Client/Server Session 要結束一個客戶/服務模式會話,服務端調用IDirectPlay8Server::Close。如果沒有其他主機接管,則將結束所有連接的會話。客戶端將接收到DPN_MSGID_TERMINATE_SESSION消息. 服務端然後將接收DPN_MSGID_DESTROY_PLAYER消息從每位玩家,包括它自己。IDirectPlay8Server::Close是同步的,直到所有返回的DPN_MSGID_DESTROY_PLAYER消息都被處理才返回。當IDirectPlay8Server::Close被返回,就可以安全的關閉服務端程序。      聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-11-27 18:14:24 IP:61.218.xxx.xxx 未訂閱
DirectPlay SDK中文翻譯Understanding DirectPlay(2)      Understanding DirectPlay(2) 作者:楊冰(源代碼之光) E-mail:iceryeah2000@163.com 創建時間:2002-9-26 最後修改時間:2002-10-15 備注:被部分翻譯的是DirectPlay Lobbies章節。主要講述了DirectPlay的大廳機制。    DirectPlay Lobbies 大廳(lobby)的主要目的是安排用戶使用多個網絡遊戲,這樣的機制使不同類型的遊戲集合在一起,有利於管理和用戶選擇。大廳程序通常運行在遠程服務器上。用戶訪問大廳(可通過多種方式:通過互聯網/局域網建立一個會話或加入一個會話都可以訪問大廳)。大廳程序然後會連接運行(launch)組裡的遊戲,遊戲這時就開始運行。 因為大多多人遊戲都是擁有大廳的,基於DirectPlay的遊戲一般都支持大廳程序。這部分就是討論如何使DirectPlay遊戲具有支持大廳的功能。    DirectPlay Lobby Architecture 安排和管理基於DirectPlay多人遊戲會話的過程包括五個獨立的組件。大廳服務端程序是第三方組件(通過互聯網在遠程服務器上運行)。其余的四個組件都被安裝在用戶計算機上。 1 大廳客戶端(Lobby client)。大廳客戶端是用來和大廳服務器(lobby server)進行聯系通訊的。它主要是通過DirectPlay大廳客戶端對象(lobby client object)和用戶的遊戲程序進行通訊。 2 支持大廳的遊戲(Lobbyable game application)。它使用DirectPlay lobbied application object(大廳遊戲程序對象)和大廳客戶端進行通訊,然後再通過大廳客戶端與大廳服務端進行聯系。 3 DirectPlay大廳客戶端對象(DirectPlay lobby client object)。 4大廳遊戲程序對象(DirectPlay lobbied application object)(從lobbied被動式來講,這是對遊戲程序,表示該遊戲支持大廳,可我找不到恰當精煉的語言來表達) 上面兩個DirectPlay對象扮演了連接遊戲程序和大廳客戶端的角色。他們通過私有平台彼此進行聯系。下面的圖表示了關系和如何進行通訊聯系的。(圖片未復制,SDK有)    Lobby Servers 大廳服務器主要目的是安排角色和管理遊戲。它一般建立在遠程服務器上。大廳服務器通常還具有主持聊天,發送新聞,商品交易等功能。 要管理多人遊戲,一個大廳服務器一般要做以下任務: 1 管理安排各個遊戲會話和玩家的網絡地址。 2 通過相應的遊戲程序來連接相應的會話。 3 將角色加入現有的會話中。 4 保持會話中的電腦到正確的網絡地址。 5 追蹤會話的狀態變化,諸如角色的離開或改變遊戲主機。 具體的大廳服務器工作細節依具體的情況而定,但主要任務必須包括上述內容。    Lobby Clients 大廳客戶端是負責與大廳服務端連接的程序,它被安裝到每個玩家的電腦上。它負責玩家和他們的遊戲程序,以及服務端之間的通訊。一個安裝大廳客戶端通用的方法是叫用戶在遊戲服務主頁上進行下載。 大致的步驟如下: 1 新用戶到網站上注冊。 2 作為注冊的一部分,客戶端被下載到用戶的電腦上。 3 用戶決定玩哪個遊戲,並進入該遊戲會話。 4 網站開始連接用戶電腦上的客戶端程序。可以通過URL來指向一個客戶端執行文件。 5 大廳客戶端安排會話,並運行用戶指定的遊戲程序。 6 如果該遊戲具有支持大廳功能,大廳客戶端啟用該遊戲程序,讓遊戲程序直接和大廳服務端進行通訊。這個連接使大廳服務端保持追蹤用戶進入或者退出遊戲的事件。  大廳客戶端並不是必須和遠程服務器進行連接。用戶運行大廳客戶端後,客戶端會列出有效的遊戲和會話。一旦用戶選擇了一個遊戲和會話,大廳客戶端則開始連接運行該遊戲。 這部分討論的是大廳客戶端的一般知識。在Communicating with a Lobbyable Game.中會有對大廳客戶端和其連接的大廳服務端更多的討論。    Communicating with a Lobbyable Game 我們可以通過多種方便的方法讓大廳客戶端和與其相聯接的大廳服務端進行通訊。DirectPlay在下面具體介紹了大廳客戶端和支持大廳功能的遊戲程序如何進行通訊。 大廳客戶端不能直接的和遊戲程序進行通訊。它是通過大廳客戶端對象(CLSID_DirectPlay8LobbyClient)來和遊戲程序通訊的。這個對象是從IDirectPlay8LobbyClient界面獲得。如果遊戲程序具有大廳功能,則此程序的客戶端對象負責傳遞消息。用如下步驟使用IDirectPlay8LobbyClient對象。 1 在用戶系統上枚舉支持大廳的遊戲。 2 連接遊戲,如果此遊戲沒有運行,則連接它到會話中。 3 從會話中釋放此遊戲,並且關閉和大廳客戶端的連接。 4發送消息給已經連接的遊戲。 Note 大廳客戶端可以運行任何程序,不管此程序是否具有支持大廳功能。不過,隻有支持大廳的遊戲程序才能使用DirectPlay去和大廳客戶端進行通訊。 大廳客戶端對象和大廳客戶端進行通訊是通過回調函數進行的。函數指針在初始化期間被傳遞到大廳客戶端對象。回調函數發送的消息如下: 1 連接信息。 2 連接狀態。 3 會話狀態,其中包括連接的,未被連接的和主持會話的主機。 4 從遊戲程序發送到大廳客戶端的消息。 運行(launch)一個程序 當你運行一個程序,你可以試圖傳遞一個關於遊戲具體情況的數據塊給程序。當支持大廳的遊戲被一個大廳客戶端運行,則此遊戲創建和初始化一個支持大廳程序對象(lobbied application object)。信息則通過此對象被傳遞到遊戲。 當lobbied application object被初始化,則大廳客戶端接收到消息來判斷用戶是否已經被連接。傳遞這個信息的主要目的就是為了讓大廳客戶端知道此遊戲是否具有支持大廳功能。如果大廳客戶端在運行此遊戲的一段時間內,沒有接收到這樣的連接信息,則表示此遊戲不具有支持大廳功能。你就可以停止這次連接。 運行程序後 此期間,大廳客戶端和正在運行的支持大廳遊戲相比沒有作很多的工作。依靠遊戲拓撲,大多的用戶信息被直接發送到遊戲服務器。不過,DirectPlay在發生斷開連接和主機時,發送消息給大廳客戶端。這些消息是為了讓大廳客戶端知道服務器當前的狀態。比如,如果主機改變,大廳服務端會更新UI,指示新的主機。 遊戲也能向大廳客戶端傳遞消息。這些消息可以包括任何內容,它能被用於任何目的。大廳客戶端一般傳送數據給大廳服務端去處理。比如,在遊戲的結束時,遊戲可能會發送一段消息告訴大廳服務端,有新的分數紀錄產生,請更新最高分列表。    Lobbyable Applications 具有大廳功能的程序(Lobbyable applications,翻譯繁瑣,以後直接引用英文)被設計直接和大廳客戶端進行工作。當大廳客戶端使用DirectPlay運行程序,Lobbyable applications在此時會顯現出如下優點: 1 當遊戲狀態改變時,大廳客戶端自動接收更新信息。 2 大廳客戶端可以使用標準API來和遊戲進行通訊。 3 遊戲同時也能使用標準API來和大廳客戶端進行通訊。 總之,DirectPlay實際上消除了遊戲本身對網絡通訊的硬編碼。你可以在任何時候使用標準API或者基於其上,通過少量修改達到遊戲的網絡通訊要求。 在Launching a Lobbyable Application會有更多的關於lobbyable application的信息。 如果想知道lobbyable application具體的工作機理,查看Implementing a Lobbyable Application章節和SDK中SimplePeerhe和StagedPeer例子。    Launching a Lobbyable Application 當Lobbyable Application被運行後,首要做的是創建一個支持大廳功能程序對象。這個對象將賦予程序判斷它是否真的被大廳運行。Lobbyable Application必須通過消息管理回調函數接收從大廳客戶端發送的消息。從下列步驟來完成: 1 創建Lobbyable Application對象。 2 初始化該對象。 3 如果初始化返回一個有效值,則遊戲被大廳連接運行。 4 檢驗在初始化階段返回的用戶的索引(context value)。這裡包含?遊戲的具體信息。 5 檢驗從lobbied application發送過來的連接消息。此消息中包括消息發送ID,依據此ID來給發送消息到大廳客戶端。 當遊戲成功的被大廳連接運行,DirectPlay就能自動的發送狀態更新信息給大廳客戶端。要開啟自動狀態更新機制,在IDirectPlay8Peer, IDirectPlay8Client, 或 IDirectPlay8Server接口中調用RegisterLobby。你也可以使用lobbied application接口來發送消息給大廳客戶端。 需要注意的是,你的消息回調函數可能在大廳客戶端初始化以前就接收到消息,除了接收到連接信息,大廳客戶端改變連接設置或斷開連接時,回調函數也會接收到消息。大廳客戶端也能直接的發送消息到你的消息管理器上。 Note 最好使用多線程來接收消息。為了正確的管理消息,lobbied application回調函數應該具有多入口(re-entrant)。     聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-11-27 18:15:43 IP:61.218.xxx.xxx 未訂閱
DirectPlay SDK中文翻譯Understanding DirectPlay(3)      DirectPlay Callback Functions and Multithreading Issues     作者:楊冰(源代碼之光) E-mail:iceryeah2000@163.com 創建時間:2002-10-24 最後修改時間:2002-10-26    備注:感覺這章翻譯的不是很透徹,可能是因為多線程的知識比較欠缺    DirectPlay需要你注冊幾個回調函數來管理消息的響應。DirectPlay可以同時處理多個線程任務。DirectPlay通過線程池(thread pool)的技術來完成對多線程的管理,你所用的線程是這個池子所提供的。線程池的大小是通過Windows2000的進程處理準則規定的。這方面的知識你可以查看Mircrosoft Developer Network documents或者Win32 的多線程參考部分。 為了正確且可靠的從DirectPlay回調處接收到數據,你最好使用多線程同步技術。同步技術將有助你保持線程安全。    微軟的操作系統提供三種方法來保持在多線程中數據的同步。    1 Mutex Objects 2 Semaphore Objects 3 Critical Section Objects    在DirectPlay Voice例子中使用了Critical Section Objects技術來同步數據。如果你希望使用前兩種方法,在Microsoft Platform SDK中有查。同步技術的運用需要有較強的能力,SDK廢話太多,就是說這個技術很不容易運用。 DirectPlay線程模塊已經被最大程度的優化,在執行"send"操作和"indication"消息時(包括接收消息),沒有線程設置開關,也就是不允許多個線程同時執行這兩項操作,每次send隻有一個線程,其它線程進行等待。(這段話翻譯的不好:there are no thread context switches during "send" operations and during "indication" messages, including receive messages.)    DirectPlay Networking Callbacks DirectPlay用於網絡得回調函數是PFNDPNMESSAGEHANDLER類型的。依靠這種類型的網絡會話,你可以用IDirectPlay8Peer::Initialize, IDirectPlay8Client::Initialize, 和IDirectPlay8Server::Initialize來注冊回調函數。    同步問題 當在回調函數處理過程中,必須使用一個同步對象來保持遊戲數據可靠。 為了理解你的遊戲數據如何成為不可靠的,可以這樣來考慮,在回調響應中,第一個線程將一段數據添入到結構體。如果另外一個線程在第一個線程沒有執行完畢之前,進入回調中,並且試圖操作那個結構體中的數據(同一個內存塊中)。因此,被第一個線程更新的結構被第二個線程重新覆蓋,導致了數據的錯誤。請注意到這隻是多線程中一個簡單的情況。 在Implementing a DirectPlay Networking Callback Using Critical Section Objects有一個例子,講述如何在會話中同步數據。    Worker Threads 你可以自己定義一個"Worker Threads"。Worker Threads是另外一個多線程程序,它基於DirectPlay回調函數來處理遊戲數據。這種方法的作用是在DirectPlay回調線程中接收數據緩存,。一個新的線程被創建,並且一個消息被發送到你的Worker Threads回調中,來標記處理緩沖數據。    Multithreading Performance Issues and Asynchronous Operations 需要慎重考慮在回調過程中處理信息所花的時間來。如果你有大量的信息在一個回調過程中,並且你使用了數據鎖定來同步線程數據,你就會遇到線程堵塞問題。    如果你選擇了worker thread和在另外一個回調中進行遊戲數據的處理補償,你就增加了CPU的處理時間。如果你在worker thread中設置了一些非關鍵性的數據處理過程,數據處理會更加佔用CPU時間。    你可以在回調過程中返回DPNSUCCESS_PENDING,創建一個數據緩沖指針,然後使這個指針在worker thread中有效。當worker thread處理完了遊戲數據,你就可以調用ReturnBuffer方法,來完成上述步驟。(IDirectPlay8Peer、 IDirectPlay8Client所提供的ReturnBuffer方法)    聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
happosai
高階會員


發表:93
回覆:228
積分:109
註冊:2002-09-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-01-08 00:27:37 IP:218.166.xxx.xxx 未訂閱
路人亂入: there are no thread context switches during "send" operations and during "indication" messages, including receive messages 這一句的意思是指,當 send or receive 時不會被其他的 thread 打斷,也就是不會發生 context switch,為什麼 DirectPlay 的文件要提這個?有寫過 socket 的人就知道,當一個thread正在對一個 socket handle 送出資料時,若有另一個thread也對這個handle送出資料, 因為context switch造成交叉傳送,結果是接收端收到錯誤的資料,原因是 socket並非thread-safe,send&receive並非atomic運算(不可分割),所以 得自行加上mutex, critical section等機制。 我是以我的經驗這麼解釋,若有錯誤還請各方先進指正
系統時間:2017-10-18 9:43:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!