Send data with winsock

Started by
29 comments, last by hplus0603 19 years, 4 months ago
Regarding the previous printing problem, you don't print a "float" using %s; you print a "float" using %f. I still don't think you've gotten the difference between memory, a buffer, a pointer, a float, and a char down. To do network programming, it's important that you understand the basic tools of your programming language first.
enum Bool { True, False, FileNotFound };
Advertisement
well, the %f was what we were missing the whole time. Although we have solved our problem with everyones help here, I think this just shows that we are no where ready to takle more complex problems with winsock. If anyone has a good tutorial using send and recieve, we would greatly appreciate it.

Thanks, Steers
hey Steers. to be honest, i don't think you are at all ready to try to learn network programming. i'm not trying to be harsh, or rude. but from your post i another forum and from this one, it is clear you are not ready. i am only posting this so that you don't get very frustrated, and give up because your stuck on a problem that has to deal with the basics of the language. if you start from the bottom, and work your way up, you have a much greater chance of succeeding.

anyway, good luck in whatever you do.
FTA, my 2D futuristic action MMORPG
If you were refering to including the librarys in Visual c++, i've been using a different compiler. We are not stupid programmers. And i don't doubt that winsock and network programming can be challanging. However, whether it is too difficult i believe should be decided by us. But thank you for your concern. We would really only like resources to learn from rather than demotivation.
whoops, sorry. i was confusing you with this thread.

although, to be honest, my comment still applies a little to you. finding basic error messages like the ones you struggled with kind of jumps out at me like your biting off too much to chew. and please dont be offended by it or feel i was trying to make you un-motivated. i was actually only trying to help, believe it or not. part of being a programmer is learning how to take constructive critisism [smile].
FTA, my 2D futuristic action MMORPG
Biting off more than we can chew? Possibly, but we arent concerned about that. Right now we'd rather jump into it and sink than learn to swim first; not because we are ignorant or arrogant, but just because it doesnt make a differance if we make it or not. And if we don't try now, then theres no point. Thats all, thank you for your concern.

I'll google winsock and see what comes up...
Btw steers,
Just out of pure curiosity...

Do you still use that "memcpy madness"(tm) or are you going with the struct?
Our proof of concept now works with both methods, however we are not sure why you would use one over the other. Is one method more effecient?
you shouldn't break your head about efficiency in this early stage.
But what method looks easier to maintain?
I mean, c'mon, using memcpy to write a float (4 bytes) when you could
as well use "a = 1.34f"... ;)

And I would claim that the memcpy version is much more slower, yes...
:) Anyway, you got it working now... good job
personally, i prefer to use the "memcpy madness". one main reason - if you ever want your game to be cross platform, you are screwed. you can't just send a struct over the wire like that, you would have to pick it apart and write each member to network byte order before sending it, and im pretty sure you would wind up having to memcpy it into a char array anyway... (please someone correct me if im wrong).

besides, it would be foolish to manually use memcpy() each time you wanted to send data. make a class to do it for you! heres the one i made a while back:

first, the OutPacket class, that you use to send packets:

#ifndef SMART_PACKET_H#define SMART_PACKET_H#include "enet.h"#include "Networking.h"class OutPacket{	public: 		OutPacket(enet_uint8 msg_type);		OutPacket(enet_uint8 *buff,const int buff_size);		~OutPacket(){}				void Send(ENetPeer *peer,enet_uint32 packet_flags = NULL);		void Send(enet_uint8 network_id,enet_uint32 packet_flags = NULL);		void Broadcast(enet_uint32 packet_flags = NULL);		 		void Add_Data(enet_uint8  data);		void Add_Data(enet_uint16 data);		void Add_Data(enet_uint32 data);		void Add_Data(enet_sint8  data);		void Add_Data(enet_sint16 data);		void Add_Data(enet_sint32 data);				void Add_Data(const char *string);		  		static void Set_User(ENetHost *host){user = host;}    private:  		int pos;		char buff[MAX_PATH];		//set this to the server in the server and client in the client		static ENetHost *user;};#endif#include "OutPacket.h"#include "Networking.h"#include <assert.h>ENetHost* OutPacket::user = NULL;OutPacket::OutPacket(enet_uint8 msg_type){  pos = 0;  memcpy(buff,&msg_type,1);  pos++;}//this ctor is for when i want to forward a packet usuaully//i can just send this OP a enet_uint8 * which will fill in the data for meOutPacket::OutPacket(enet_uint8 *buff,const int buff_size){  pos = 0;  memcpy(this->buff,buff,buff_size);  pos+=buff_size;}void OutPacket::Send(ENetPeer *peer,enet_uint32 packet_flags){  //set channel based if its reliable or not  const enet_uint8 channel = packet_flags == NULL ? CHAN_UNRELIABLE : CHAN_RELIABLE;  //make the packet of size pos  ENetPacket *pack = enet_packet_create(buff,pos,packet_flags);   //pack will be null if create failed  assert(pack);     enet_peer_send(peer,channel,pack);  enet_host_flush(user);}void OutPacket::Send(enet_uint8 network_id,enet_uint32 packet_flags){    //first, grab the peer who match's up to the network ID. IE, convert from id -> peer	ENetPeer *reciever = NULL;		for(int i = 0; i < user->peerCount; i++)	{		if(user->peers.address.host == 0)			continue;		enet_uint8 tmp;		memcpy(&tmp,user->peers.data,1);		if(tmp == network_id)			reciever = &user->peers;	}  //assert that we found the peer!!!, if not, then he's not connected to us  //or the ID is invalid.  assert(reciever);  //set channel based if its reliable or not  const enet_uint8 channel = packet_flags == NULL ? CHAN_UNRELIABLE : CHAN_RELIABLE;  //make the packet of size pos  ENetPacket *pack = enet_packet_create(buff,pos,packet_flags);   //pack will be null if create failed  assert(pack);     enet_peer_send(reciever,channel,pack);  enet_host_flush(user);}void OutPacket::Broadcast(enet_uint32 packet_flags){  const enet_uint8 channel = packet_flags == NULL ? CHAN_UNRELIABLE : CHAN_RELIABLE;  ENetPacket *pack = enet_packet_create(buff,pos,packet_flags);  assert(pack);  enet_host_broadcast(user,channel,pack);  enet_host_flush(user);}void OutPacket::Add_Data(enet_uint8 data){  memcpy(buff + pos,&data,1);  pos++;}void OutPacket::Add_Data(enet_uint16 data){  WriteToBuff16(buff + pos,data);  pos += 2;}void OutPacket::Add_Data(enet_uint32 data){  WriteToBuff32(buff + pos,data);  pos += 4;}void OutPacket::Add_Data(enet_sint8 data){  memcpy(buff + pos,&data,1);  pos++;}void OutPacket::Add_Data(enet_sint16 data){  WriteToBuff16(buff + pos,data);  pos += 2;}void OutPacket::Add_Data(enet_sint32 data){  WriteToBuff32(buff + pos,data);  pos += 4;}void OutPacket::Add_Data(const char* string){	if(strlen(string) <= 255)	 {		 enet_uint8 tmp = (enet_uint8)strlen(string);		 memcpy(buff+pos,&tmp,1);		 pos++;		 memcpy(buff+pos,string,strlen(string));	     pos += (int)strlen(string);	 }	else	{		enet_uint16 tmp = (enet_uint16)strlen(string);		memcpy(buff+pos,&tmp,2);		pos+=2;		memcpy(buff+pos,string,strlen(string));		pos+= (int)strlen(string);	}}


now the InPacket class:

#ifndef INPACKET_H#define INPACKET_H#include "enet.h"#include "Networking.h"class InPacket{  public:		  	    //init pos to 1, skipping the first byte  of buff, since its the header of the packet 		InPacket(enet_uint8 *buff) : buff(buff),pos(1){}		~InPacket(){}		void GetNextItem(enet_uint8 &data);		void GetNextItem(enet_uint16 &data);		void GetNextItem(enet_uint32 &data);		void GetNextItem(enet_sint8 &data);		void GetNextItem(enet_sint16 &data);		void GetNextItem(enet_sint32 &data);		void GetNextItem(char *string,const int header_size = 1);   private:		 		int pos;		enet_uint8 *buff;  };#endif#include "InPacket.h"#include "../Common/Networking.h"#include <assert.h>void InPacket::GetNextItem(Uint8 &data){	memcpy(&data,buff+pos,1);	pos++;}void InPacket::GetNextItem(Uint16 &data){	data = ReadFromBuff16(buff+pos);	pos+=2;}void InPacket::GetNextItem(Uint32 &data){	data = ReadFromBuff32(buff+pos);	pos+=4;}void InPacket::GetNextItem(Sint8 &data){	memcpy(&data,buff+pos,1);	pos++;}void InPacket::GetNextItem(Sint16 &data){	data = ReadFromBuff16(buff+pos);	pos+=2;}void InPacket::GetNextItem(Sint32 &data){	data = ReadFromBuff32(buff+pos);	pos+=4;}void InPacket::GetNextItem(char *string,const int header_size){	assert(header_size == 1 || header_size == 2);	if(header_size == 1)	{		Uint8 sz;		memcpy(&sz,buff+pos,1);		pos++;		memcpy(string,buff+pos,sz);		pos+=sz;		//dont forget to add newline		string[sz] = '\0';	}	else 	{		Uint16 sz;		memcpy(&sz,buff+pos,2);		pos+=2;		memcpy(string,buff+pos,sz);		pos+=sz;		//dont forget to add newline!!!		string[sz] = '\0';	}}

(note, enet_uint8 is a #defined unsigned char, enet_uint16 is an unsigned short, and enet_uint32 is an unsigned long)

now, using these classes, sending and receiving data is simple. for example, if you wanted to send your X/Y/Z position, it would look like this:

OutPacket op(MSGID_MY_POSITION);op.Add_Data(x);op.Add_Data(y);op.Add_Data(z);op.Send();


and, receiving it is very simple as welll:

float x,y,z;InPacket ip(packet_data);ip.GetNextItem(x);ip.GetNextItem(y);ip.GetNextItem(z);


thats it! very simple, and best of all you are encapsulating this all into a nice little class. this way, if you ever had to make changes, you only have to change the functions. for example, if you ever switched networking libraries for some reason, you would only have to change sending code in that single Send() function, instead of all over the place. plus, now everything is written in the proper order. also note, you can still send structs over the wire this way, by just making a small change to the Add(char *) and Get(char *) functions. obviously, you dont have to do this *exactly* how i did, but this should give you a good idea.

good luck.
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement