2011-02-06 37 views
0

我還是讓我的周圍指針頭之類的,所以這裏去發...類型轉換結構的數組(指針的?),以通過Winsock

  • 每個客戶端發送的位置播放器正確到服務器。
  • 在服務器上的數據然後被放入一個結構數組(或指向結構?)。該陣列的數據也被證實是正確的。
  • 然後服務器意味着將該陣列中的所有數據發回給每個玩家
  • 我希望能夠將數組從服務器發送到客戶端(並且再次返回),因爲它是方法我想把我的頭腦理解爲一些(或者指向結構的指針數組),例如,子彈和射擊的數組或其他東西。
  • 我並不擔心目前或優化代碼的帶寬,是後話,當我明白這一切更好:)

基本上我已經創建了一個結構爲我的球員: -

struct PlayerShip 
{ 
    unsigned int health; 
    unsigned int X; 
    unsigned int Y; 
}; 

然後我創建了一個陣列(從朋友的指導),讓我來訪問這些結構的數據(和它們強制類型轉換爲需要)(我認爲)

PlayerShip *playerArray[serverMaxClients]; 
for (int i = 0; i < serverMaxClients; i++) 
{ 
    playerArray[i] = new PlayerShip; 
    ZeroMemory(playerArray[i],sizeof(PlayerShip)); 
} 

I RECV從所有連接的播放器的數據並將其饋送到陣列

for (int slotIndex = 0; slotIndex < serverMaxClients; slotIndex++) 
{ 
    char szIncoming[1500]; 
    ZeroMemory(szIncoming,1500); 
    int connectionStatus = recv(clientSocketArray[slotIndex], (char*)szIncoming,sizeof(szIncoming),0); 

    playerDataTemp = (PlayerShip*)szIncoming; 
    playerArray[slotIndex]->X = playerDataTemp->X; 
    playerArray[slotIndex]->Y = playerDataTemp->Y; 
} 

打印出該陣列,所有的數據是正確的。

所以下一步就是將數據發送回客戶端。我試着改變變量爲引用和/或指針(我仍然沒有那個頓悟的時刻,其中指針和引用突然變得有意義),或者值不正確。 (下面的情況下,當前輸出不正確的值)

 for (int i = 0; i < serverMaxClients; i++) 
    { 
     char* outgoing = (char*)playerArray; 

     if (clientSlotTaken[i] == true) 
     { 
       send(clientSocketArray[i],outgoing,sizeof(playerArray),0); 
     } 

     int *valueCheck; 
     valueCheck = (int*)outgoing; 
     cout << "VALUE CHECK " << valueCheck << "\n"; 

     delete outgoing; 
    } 

的「值檢測」我期待爲「100」的應該是100播放器1的健康被髮送到服務器的前面。


UPDATE

Okie現在我開始讓我的頭周圍多一點。

playerArray是指向結構體的指針數組。所以我不想將數組中的原始數據發送給客戶端。我想將結構的數據發送給玩家。

所以我猜我必須有一些代碼創建一個char數組,我用所有玩家結構中的數據填充。

我嘗試了以下,但...

 char outgoing[120]; 
     PlayerShip *dataPopulator; 
     dataPopulator = &outgoing[0]; //Start at the begining of the array 

     for (int i=0; i < serverMaxClients; i++) 
     { 
      *dataPopulator = playerArray[i]; 
      dataPopulator++; 
     } 

我收到以下錯誤

  • 在分配無法轉換 '的char *' 到 'PlayerShip *' |
  • 在'* dataPopulator = playerArray [i]'中'operator ='不匹配。

由於Joriki,這幫助我瞭解多一點,但我仍然有很長的路要走:\仍然可以通過大量的網頁,嘗試解釋指針和閱讀等

回答

1
PlayerShip *playerArray[serverMaxClients]; 

聲明一個serverMaxClients指針數組,每個指針指向一個PlayerShip結構。

這裏

char* outgoing = (char*)playerArray; 

你指的是這個數組的指針的地址,所以你要send通話將發送一串三分球,這是幾乎可以肯定不是你想要的。此外,這裏

delete outgoing; 

你想刪除這個數組指針,這是在棧上,而不是從堆中分配的,所以這可能導致重大問題;另外,您在每次迭代中刪除相同的指針。

我認爲下面更接近你打算做什麼:

 for (int i = 0; i < serverMaxClients; i++) 
    { 
     char* outgoing = (char*)playerArray [i]; 

     if (clientSlotTaken[i] == true) 
     { 
       send(clientSocketArray[i],outgoing,sizeof(PlayerShip),0); 
     } 

     int *valueCheck; 
     valueCheck = (int*)outgoing; 
     cout << "VALUE CHECK " << *valueCheck << "\n"; 

     delete outgoing; 
    } 

該發送數據的PlayerShip結構,而不是僅僅依賴機器的指針,然後將其釋放的通過「new PlayerShip」在堆上分配的內存,而不是在堆棧上分配的指針數組。還要注意值檢查的輸出語句中添加了星號;你輸出的是一個指針而不是被指向的值。 (即使你添加了星號,你也只是得到了陣列中第一個指針的int cast,而不是它指向的PlayerShip結構中的健康值。)

我希望有幫助;如果我沒有說清楚,可隨時在評論中提出進一步的問題。

更新響應ChiggenWingz的意見和UDPATE:

如果你想所有的數據發送到每個客戶端,我看到三個選項:

1)可以代替我的代碼send與一個循環:

if (clientSlotTaken[i] == true) 
    { 
     for (int j = 0;j < serverMaxClients;j++) 
      send(clientSocketArray[i],(char*)playerArray [j],sizeof(PlayerShip),0); 
    } 

但我假設你試圖避免,因爲它可能會使I/O效率較低。

2)你可以做你試圖在你的更新做。要解決您列出的錯誤,並使其工作:

a)您需要爲char *轉換爲PlayerShip *,就像你不得不四處投其他方式在你前面的代碼。

b)在副本分配中,左邊有一個PlayerShip,右邊是一個PlayerShip *,您需要取消引用該指針。

c)使用像120這樣的固定長度是非常危險的;如果你以後有更多的客戶,這可能會溢出;大小應該是serverMaxClients * sizeof(PlayerShip)。

d)「&傳出[0]」與「傳出」是同義的。

把所有一起:

char outgoing[serverMaxClients * sizeof (PlayerShip)]; 
    PlayerShip *dataPopulator; 
    dataPopulator = (PlayerShip*) outgoing; //Start at the begining of the array 

    for (int i=0; i < serverMaxClients; i++) 
    { 
     *dataPopulator = *playerArray[i]; 
     dataPopulator++; 
    } 

3)我認爲最好的選擇是將所有的PlayerShips在一個連續陣列,而不是單獨地一起分配。你可以做到這一點無論是在堆棧或堆上,根據您的喜好:

a)在堆:

PlayerShip *playerShips = new PlayerShip [serverMaxClients]; 
ZeroMemory (playerShips,serverMaxClients * sizeof(PlayerShip)); 

b)在堆棧:

PlayerShip playerShips [serverMaxClients]; 
ZeroMemory (playerShips,sizeof(playerShips)); 

(該ZeroMemory在a)中的調用也將在b)中工作,但不是相反的方式)。

現在,獨立於您如何分配連續數組,您可以將整個數據寫入每個客戶端,如下所示:

for (int i = 0; i < serverMaxClients; i++) 
    if (clientSlotTaken[i] == true) 
      send(clientSocketArray[i],(char *) playerShips,serverMaxClients * sizeof(PlayerShip),0); 

(再次,在情況b)你可以用sizeof(playerShips)代替尺寸計算。

我希望進一步明確的事情 - 但如果你仍然感到困惑:-)

+1

只是測試你的變化隨時請教一下指針更一般的問題,如果我理解正確的話,服務器通過Send()命令一次只發送一個playerShip結構體。我希望能夠將整個陣列發送回每個客戶端。上面的for循環應該將數組發送到每個連接的客戶端。 ValueChecked的工作,謝謝:) – ChiggenWingz 2011-02-06 04:30:20