通过winsock发送一系列结构(指针?)

时间:2011-02-06 03:10:48

标签: c++ arrays pointers casting

我仍然专注于指针之类的东西,所以这里......

  • 每个客户端都将播放器的位置正确发送到服务器。
  • 然后在服务器上将数据放入结构数组(或指向结构体?)。该阵列的数据也经过验证是正确的。
  • 然后服务器将该阵列中的所有数据发送回每个玩家
  • 我希望能够将数组从服务器发送到客户端(并再次返回),因为这是我想要理解的方法,我理解的是(或者指向结构的指针数组?)例如,子弹和射击阵列,或其他东西。
  • 我现在并不担心带宽或最佳代码,后来当我更好地理解它时:)

基本上我为我的玩家创建了一个结构: -

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));
}

我从所有连接的播放器中恢复数据并将其输入数组

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”,因为这应该是玩家1早先发送到服务器的100的健康状况。


更新

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 个答案:

答案 0 :(得分: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强制转换,而不是它指向的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)“&amp; outgoing [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)我认为最好的选择是将所有PlayerShip一起分配到一个连续的数组而不是单独分配。您可以根据需要在堆栈或堆上执行此操作:

a)在堆上:

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

b)在堆栈上:

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

(a中的ZeroMemory调用)也适用于b),但不是相反。)

现在,无论您如何分配连续数组,您都可以将整个数据写入每个客户端,如下所示:

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

(同样,在b的情况下)你可以用sizeof(playerShips)替换大小计算。

我希望进一步澄清事情 - 但如果你仍然感到困惑,可以随意提出更多关于指针的一般性问题: - )