send with winsock

Started by
6 comments, last by Xelot 22 years, 5 months ago
Im using Winsock 2 with VC. I read some where that its possible to send any type (such as a struct that I make) with Winsock. I look at the prototype for send() and sendto() in WSAPI22.DOC and they both take a pointer to a char for what to send. How can I send a struct instead of a char array?
Advertisement
This code should work.
You can use a similar system for Recieveing data as well.


  #define SAFERELEASE(x) if (x != NULL){delete x; x = NULL;}////////////////////////////////////////////////////////// Send Struct Returns True if It''s Successful////////////////////////////////////////////////////////bool SendStruct(void* pData, int nSize, socket socketID){// Localschar* byData = NULL; // Initalize a char array and set to NULL// Allocate StringbyData = new char[nSize];// Copy Data. NOTE! Does Not Swap Endian!memcpy(byData, pData, nSize);//Send Stringif (send(m_Connection, bySendBuffer, nSize, NULL) != nSize){	SAFERELEASE(bySendBuffer);	return false;}SAFERELEASE(bySendBuffer);return true;}  
------------------------------------------------------------I wrote the best video game ever, then I woke up...
this is better and doesnt require the memcpy
just cast it to a char*
  struct MyStruct{  // data stuff in here};...MyStruct data;...send(m_Connection, (char*)&data, sizeof(MyStruct), NULL);  



"I pity the fool, thug, or soul who tries to take over the world, then goes home crying to his momma."
- Mr. T
What if the structs members is aligned at, say, 4 bytes boundries?. Wouldn''t send miss some bytes then?
Why would send miss something? You just give it a pointer to the data, and then the size of the buffer, and sizeof() just returns the size of the struct.

Of course you waste a few bytes here and there if alignment rules actually kick in. You might want to set the structures to be byte packed (using #pragmas or attributes, depending on the compiler).

I''m a bit confused though... send() should really take a void * pointer, because it completely ignores the format of the data that is being sent. Prototypes using char * are logically broken (or does this mean that MS assume you''re sending text and therefore scan the data for private data? ).

cu,
Prefect

One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
Thanks people for your help. I got sending and receiving a struct to work but I have a problem. I am writing a high level Winsock wrapper. I want my send function to take only one parameter - a pointer to the data. If I do sizeof(Type) that works but my send function wont know what type it is so I have to do sizeof(Object) but it misses some bytes that way. How should I do it?
Well, you have to pass the size of the data along with the data itself.

The only possible alternative would be to use a C++ wrapper class like this:

  class CData {public:	virtual int GetSize() = 0;	virtual void *GetData() = 0;};  


You would then of course inherit this class for the various different types (like int, structs, etc...), overloading the GetSize and GetData members.

Your send() function would then just take a pointer to CData. It''d then call GetSize and GetData to get the information it needs to send the packet.

However, I doubt that this is really worth it.

cu,
Prefect

One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
I am also currently experimenting my way through a winsock program, and I have found that using a single union to represent all of the different types that can be sent, coupled with a packet type byte and a function that determines packet size from the type works very well.

E.g.
  union Packet {BYTE id;struct {  BYTE id;  char textdata[10]; //or whatever} packet1;struct {  BYTE id;  double doubleVar;  //or whatever  int etc;} packet2;}  


Then, when I want to send a packet:
  Packet pack;pack.id = PACK_ID_PACK1; //constant defined elsewherestrcpy(pack.packet1.textdata, "hello");send(socket, (char *)&pack, getSizeOfPacket(PACK_ID_PACK1), 0);  


Then when receiving, I first recv just one byte to get the packet ID number, and figure out how much more data I have to receive from getSizeOfPacket. Then I recv the rest of the packet and decide what to do with it based on the packet type. I just like the simplicity of using one type for all of the packets, while retaining the flexibility to send any kind of data you want.
--Riley

This topic is closed to new replies.

Advertisement