Advertisement

Revc&Send packets

Started by January 08, 2003 02:33 PM
4 comments, last by logout 22 years, 1 month ago
in my socket wrapper i need to be able to send packets. i got a base packet class like this :

struct tBasePacket
{
  int iType;
  int iSize;
  int iCheckSum; // Its iType+iSize
};
 
when i want a new type of packet i inherit it from the BasePacket.

struct tCarMove : public tBasePacket
{
   int iDir;
   int iSpeed;
};
 
i got the methods :

int Send(char *szBuffer, size_t iSize);
int Revc(char *szBuffer, size_t iSize);
 
And i am 100% these works. They return the number of bytes recved. I am using TCP/IP. *Will later chage it into UDP* What i need is a way to send the packets over the nettwork. Like:

int CSocketTCP::SendPacket(char *szData, size_t iSize)
{
   int iSendt = 0;
   
   while(iSendt < iSize)
      iSendt =+ Send(szData, iSize);

}
 
i know this dont work. Not sure why .... But if anybody can write a quick outline of how the RecvPacket() SendPacket() sould look like it whold have been a great help ! *and i know that TCP is a stream based protocol...*
This is something I threw together... It doesn''t have enough error checking, and is really overly simple, but it should give you an idea...


  bool CSock::SendPacket(tBasePacket * pPkt){	int nSent = 0;	int nTotalSent = 0;	//Send until the whole message is sent	while(nTotalSent < pPkt->iSize)	{		//Send whatever is left to be sent		nSent = send(m_hSocket, (const char *)(pPkt + nTotalSent), pPkt->iSize - nTotalSent, 0);		if(nSent == 0)			//Connection Closed			return false;		nTotalSent += nSent;	}	return true;}bool CSock::RecvPacket(tBasePacket ** ppPkt){	//temporary buffer to receive packet	char chBuf[MAX_PACKET];	ZeroMemory(chBuf, MAX_PACKET);	tBasePacket *pPkt = (tBasePacket*)chBuf;	int nRecvd = 0;	int nTotalRecvd = 0;		//Get at least the packet header defined by the base packet type so we can check iSize to see how much we need to receive	while(nTotalRecvd < sizeof(tBasePacket))	{		nRecvd = recv(m_hSocket, chBuf, sizeof(tBasePacket), 0);		if(nRecvd == 0)			//Connection Closed			return false;		nTotalRecvd += nRecvd;	}		//Now that we have an entire header, check the iSize member and receive one whole packet.  No more, no less	while(nTotalRecvd < pPkt->iSize)	{		nRecvd = recv(m_hSocket, chBuf, pPkt->iSize - sizeof(tBasePacket), 0);		if(nRecvd == 0)			//Connection Closed			return false;		nTotalRecvd += nRecvd;	}	//Allocate space on the heap for the packet, copy from temporary buffer to that and return 	*ppPkt = (tBasePacket*)new char[pPkt->iSize];	memcpy(*ppPkt, pPkt, pPkt->iSize);	return true;}  
Advertisement
Hm.. i got a question : what i wanted to send a diffrent type of packet ? Like the tCarMove packet i showed in my first post.


nSent = send(m_hSocket, (const char *)(pPkt + nTotalSent), pPkt->iSize - nTotalSent, 0); 


And i dont quite get the second paramenter in send():
(const char *)(pPkt + nTotalSent) 

You typecast the tBasePacket but how can you pluss a intreger
and a struct *tBasePacket ?
That's a little pointer arithmetic. Pretend you have something like

char numbers[4];
numbers[0] = 96;
numbers[1] = 97;
numbers[2] = 98;
numbers[3] = 99;

char *pNumber = numbers;

Then *pNumber will equal 96, as you've just referenced numbers[0]. Adding an integer to pNumber and then deferencing allows you to move through the array by incrementing the pointer:

*(pNumber + 1) = 97;
*(pNumber + 2) = 98;
*(pNumber + 3) = 99.

In reality, whenever you reference a certain slot in an array, such as

char string[256];

string[255] = '\0';

what you're really implicitly doing (and what the compiler eventually does) is *(string + 255) = '\0'. The brackets are the more human-readable way of doing things.

Thus, when you have something like

tBasePacket *packet = new tBasePacket;int bytesReceived = 0;while (bytesReceived < sizeof(tBasePacket)) {   Receive(packet + bytesReceived, sizeof(tBasePacket) - bytesReceived);}  


you're skipping the portion of the packet that's already been received by incrementing the pointer and storing the rest of the incoming data where you left off.

RapscallionGL - arriving soon.

[edited by - johnnie2 on January 8, 2003 9:06:19 PM]
________________________________________________"Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C
Did his explanation help you? He''s right, it''s just a different way of doing pointer arithmetic. A pointer is just a memory address. You could use array notation, which would look like:


    char *pchPkt = (char*)pPkt;  nSent = send(m_hSocket, (const char*)&pchPkt[nTotalSent], pPkt->iSize - nTotalSent, 0);  


But I chose to write it a different way.

And as for sending other types of messages, I am assuming that you''re setting the iSize member to the size of that structure. So the iSize for a tCarMove packet would be set to sizeof(tCarMove) before you pass it to the send function. So it doesn''t matter what the data is in the tCarMove packet passed to send, it will send the whole structure up to iSize bytes.

Any other questions?
yeah ...
where do the extra information tCarMove have : get stored ?

This topic is closed to new replies.

Advertisement