I’m still getting my head around pointers and the like, so here goes…
- Each client sends the position of the player correctly to the server.
- On the server the data is then put into an array of structs (or points to structs?). The data of that array has also been verified to be correct.
- The server then is meant to send all the data in that array back to each of the players
- I would like to be able to send arrays from the server to the client (and back again) as the it is that approach I want to take in my head that I understand sort of (or arrays of pointers to structs?) eg, arrays of bullets and shooting, or other things.
- I’m not worried about bandwidth at the moment or optimal code, that comes later when I understand it all better 🙂
Basically I’ve created a struct for my player:-
struct PlayerShip
{
unsigned int health;
unsigned int X;
unsigned int Y;
};
Then I’ve created an array (from the guidance of friends) that allows me to access the data of those structs (and typecast them as needed) (I think)
PlayerShip *playerArray[serverMaxClients];
for (int i = 0; i < serverMaxClients; i++)
{
playerArray[i] = new PlayerShip;
ZeroMemory(playerArray[i],sizeof(PlayerShip));
}
I recv data from all the connected players and feed it into the array
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;
}
I print out the array and all the data is correct.
So the next step is to send that data back to the client.
I tried the following and a few variations of it, but I either get compile errors as I try to change variables into references and/or pointers (I still haven’t had that epiphany moment where pointers and references suddenly makes sense), or the value comes out incorrectly. (the below case currently outputs an incorrect value)
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;
}
The “Value Check” I’m expecting to be “100” as that should be player 1’s health of 100 that was sent to the server earlier.
UPDATE
Okie now I’m starting to get my head around it a bit more.
playerArray is an array of pointers to structs. So I don’t want to send the raw data from the array to the clients. I want to send the data of the structs to the players.
So I’m guessing I have to have a bit of code that creates a char array, which I populate with the data from all the player structs.
I tried the following but…
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++;
}
I get the following errors
- cannot convert ‘char*’ to ‘PlayerShip*’ in assignment|
- no match for ‘operator=’ in ‘* dataPopulator = playerArray[i]’|
Thanks to Joriki, that help me understand it a bit more, but I still have a way to go :\ Still reading through lots of web pages that try to explain pointers and such
declares an array of
serverMaxClientspointers, each of which points to aPlayerShipstructure.Here
you’re referring to the address of this array of pointers, so your call to
sendwill send a bunch of pointers, which is almost certainly not what you want. Also, hereyou’re trying to delete this array of pointers, which was allocated on the stack and not from the heap, so this might cause major problems; also, you’re deleting the same pointer in every iteration.
I think the following comes closer to what you’re intending to do:
This sends the data in the PlayerShip structures, as opposed to just machine-dependent pointers to it, and it frees the memory allocated on the heap by “new PlayerShip”, as opposed to the array of pointers to it allocated on the stack. Note also the added asterisk in the output statement for the value check; you were outputting a pointer instead of the value being pointed to. (Even if you’d added the asterisk, you would have just gotten an int cast of the first pointer in the array, rather than the health value in the PlayerShip structure it points to.)
I hope that helps; feel free to ask further questions in the comments if I haven’t made it clear.
Update in response to ChiggenWingz’ comments and udpate:
If you want to send all the data to each client, I see three options:
1) You can replace the
sendin my code with a loop:But I assume you’re trying to avoid that since it may make the I/O less efficient.
2) You can do what you tried to do in your update. To resolve the errors you listed and make it work:
a) You need to cast the char* to a PlayerShip*, just like you had to cast the other way around in your earlier code.
b) In the copy assignment, you have a PlayerShip on the left, but a PlayerShip* on the right — you need to dereference that pointer.
c) Using a fixed length like 120 is pretty dangerous; if you have more clients later, this could overflow; the size should be serverMaxClients * sizeof (PlayerShip).
d) “&outgoing[0]” is synonymous with “outgoing”.
Putting that all together:
3) The best option I think would be to allocate all the PlayerShips together in one contiguous array instead of separately. You could do that either on the stack or on the heap, as you prefer:
a) On the heap:
b) On the stack:
(The ZeroMemory call in a) would also work in b), but not the other way around.)
Now, independent of how you allocated the contiguous array, you can write the entire data to each client like this:
(Again, in case b) you could replace the size calculation by sizeof(playerShips).
I hope that clarifies things further — but feel free to ask more general questions about pointers if you’re still confused 🙂