Send data with winsock

Started by
29 comments, last by hplus0603 19 years, 4 months ago
Quote:I'm not really grasping this concept. If you only send one float you don't use memcopy but if you have more than one, why not just repeat the code without memcopy to do it multiple times?


If you're using TCP you could do that. TCP at the application level is just a stream of data, there are no such things at packets. Issuing 10 little sends is no different than issuing 1 big one (approximately - that's not really true but you should get the basics down before worrying about the details).

If you're using UDP you probably can't do that. UDP does have a concept of packets at the application level and each time you call send you're in a different packet. Issuing 10 little sends is very different than one big one.

Lets try a different tack....

All send does is send a bunch of bytes. That's all the char* is - a pointer to bunch of bytes. If you do the memcpy then what you're doing is copying a bunch of bytes from one place to another and then sending the new copy instead of the old one.

You need to forget that "char*" means a string or a pointer to characters. In this case it doesn't. It just means a pointer to bunch of random bytes. They could be the bytes that make up a float or the bytes that make up a struct or yes even the bytes that make up a string - send doesn't care. All it cares about is getting those bytes shoved down to the net.
-Mike
Advertisement
this is starting to come together, thanks yall...
Grave,
-----------------------------
char buff[9];//9 bytes of data for storing

const unsigned char MSGID_MY_POSITION = 0;//An ID that says the bytes of this packet are x and y
float x = 40.3f;//what we want to send
float y = 35.2f;//and this too

//write the ID
memcpy(buff,&MSGID_MY_POSITION,1);//(data storage array, &data to copy,size in bytes)

//write the X position
memcpy(buff+1,&x,sizeof(x)); //buff+1 because we need to start at index 1

//write the y position
memcpy(buff+5,&y,sizeof(y));//buff+5 because we used 1-4 for our first float
------------------------------
are my comments correct?
If so this was very helpful, thank you
yes, your comments do look right.

well, this one jumped out at me a bit. "const unsigned char MSGID_MY_POSITION = 0;//An ID that says the bytes of this packet are x and y".

really, this ID is just used for your own purposes, and the name and value of it do not really matter. you just use it so you know what kind of message the packet is (so you know how much and what type of data to extract out of the packet past this single byte). for example, when you received this message, you would do something like this:

unsigned char msg_id;memcpy(&msg_id,packet_data,1);switch(msg_id){  case MSGID_MY_POSITION:  {     //its a position packet, so we should now extract 2 floats     float x,y;     memcpy(&x,packet_data+1,sizeof(x));     memcpy(&y,packet_data+5,sizeof(y));     break;  }  case MSGID_SOME_OTHER_MESSAGE:  {    //we got some other message..    break;  }  case MSGID_ANOTHER_DIFFERENT_MESSAGE:  {    //another message    break;  }  case MSGID_ETC  {    //..   break;  }}
FTA, my 2D futuristic action MMORPG
Thanks yall thats perfect. Just one last question...

EDIT - nevemind answered my own dumb question lol...

works perfectly...

Thanks, Steers
Ok, we have a problem, here's some code, any help would be greatly appreciated.
The client in this code, sends a char to the server, the char is the ID that asks for it to send a float back. The code runs fine, but instead of, displaying our float we sent (which is 1.0), it displays 0. We also display our buffer array, but it says the value is !!. The out put of the program is at the end of this code...

//here the client code (not all of it mind you, just the send and recieve stuff)
int nBytes;//number of bytes we expect to recieve...	#define MAX_SIZE 13//max size of our packet	float val1 = 0.0f;//the valuue of the float we recieve        float val2 = 0.0f//float2        float val3 = 0.0f//float3	char buffer[13];//our buffer	char id=19;//the ID that the server wil evaluate	memcpy(buffer, (char*)&id,1);//copy our message id into the buffer	size = htonl(size);//makes sure size is still kool with the server//send the size the server should expect....and make sure there were no errors sending		if ((nBytes = send(mySocket, (char*)&size, sizeof(size), 0)) == SOCKET_ERROR) {			printf("Send Failed!\n");//say we do have an error		}				size = ntohl(size);//make sure our size is still kool		//send the actual id		if ((nBytes = send(mySocket,buffer, size, 0)) == SOCKET_ERROR) {			printf("Send Failed!\n");		}	//recieve the size		nBytes = recv(mySocket, (char*)&size, sizeof(size), 0);		//recieve the float        nBytes = recv(mySocket, buffer, size, 0);//copy the id, first float, second and third        memcpy(&id, buffer,1);        memcpy(&val, buffer+1, 4);        memcpy(&val, buffer+5, 4);	memcpy(&val, buffer+9, 4);		//do we have an error		if (nBytes == SOCKET_ERROR) {			printf("Recv Failed!\n");		} 		else 		{						printf("Reply Received The Number Is : %d\n", val);		}		Sleep(9000);


//heres the server code        int nBytes;//number of bytes we will recieve        #define MAX_SIZE 13//max size of our buffer	char buffer[MAX_SIZE];//our buffer to send	unsigned long size;//how much we will recieve//recieve size from the client	nBytes = recv(clientSocket, (char*)&size, sizeof(size), 0);//did we get an error? and deal with it if we did	if (nBytes == SOCKET_ERROR) {		int error = WSAGetLastError();	   if (error == WSAECONNRESET) {		WaitForSingleObject(mutexHandle, INFINITE);		FD_CLR(clientSocket, &masterSet);		ReleaseMutex(mutexHandle);		closesocket(clientSocket);		printf("client on %d disconnected\n", clientSocket);		continue;		} else {		printf("Recv Failed!\n");		gQuitFlag = true;		break;	    }	}	if (nBytes == 0) {//if we dont have anything		WaitForSingleObject(mutexHandle, INFINITE);		FD_CLR(clientSocket, &masterSet);		ReleaseMutex(mutexHandle);		closesocket(clientSocket);		printf("client on %d disconnected\n", clientSocket);		continue;	}	size = ntohl(size);//make sure size is kool with the client	float val1;        float val2;	float val3;	char id = 19;//random id we chose for send floats	nBytes = recv(clientSocket, buffer, size, 0);//recieve the id	//if we have an error	if (nBytes == SOCKET_ERROR) {		printf("Recv Failed!\n");		gQuitFlag = true;		break;	}							val1 =  1.0f;//we chose 1.0 randomly for this program        val2 = 1.0f;        val3 = 1.0f;	memcpy(buffer, &id, 1);//copy id to our buffer	memcpy(buffer+1,(char*)&val1,sizeof(val));//copy our first float	memcpy(buffer+5,(char*)&val2,sizeof(val));//copy our second	memcpy(buffer+9,(char*)&val3,sizeof(val));//copy our third	send(clientSocket, (char*)&size, sizeof(size), 0);//send the size of our packet	send(clientSocket, buffer, 13, 0);//send the actual packet	printf("Float sent to client %d. \n", clientSocket);//ran good		printf("Message Received from client on %d : %s\n", clientSocket, buffer);//worked out ok





the output of the program is...
on the client it says...
client started
enter any key to recieve a float:
reply recieved: the number is 0

on the server it says...
server started
client on 84 connected
Float sent to client on 84 : !! <----that is the value of buffer
client on 84 disconnected


Thanks in advance for any help, and sorry if its a stupid mistake. But thats how we newbies are.
-Steers

[Edited by - Steers on December 15, 2004 5:54:27 PM]
please use [ source ] [ /source ] tags for your code ;)

even better: create a struct for your messages:

struct PosMessage{  float x,y,z;  unsigned int someStuffYouMightNeed;}//Client........PosMessage msg;msg.x = 3.145f;msg.y = 12.5f;msg.z = 9.5f;msg.someExtraStuffYouMightNeed = 0xDEADBEEF;int msgType = ID_MSG_POSITION;send(socket,(char*)&msgType,sizeof(msgType),0);send(socket,(char*)&msg,sizeof(msg),0);//Server.........int msgType;recv(socket,(char*)&msgType,sizeof(msgType),0);switch (msgType){ case ID_MSG_POSITION:  {    PosMessage msg;    recv(socket,(char*)&msg,sizeof(msg),0);    //do something with msg......  }  break; case .....:  ....  ....  break; default:  printf("Error, unknown message received.\n");  break;}

****EDIT***
Don't know, however if thats gonna be an issue with byte alignment and stuff...
something similar works for me though.
Thanks madhed, except for that dead beef comment... lol

We created a struct but when we tried to send it, it said...

error C2664: 'recv' : cannot convert parameter 1 from 'unsigned int (__stdcall *)(int,int,int)' to 'unsigned int'

are we forgetting something? we copied and pasted your code, then changed it to our variables...
That error means you tried to assign "recv" without parentheses. This code will generate the same error:

#include <unistd.h>int x = recv;

enum Bool { True, False, FileNotFound };
Hi again.

I know what the problem is.... well I think I know.

the socket's variable name is 'socket' but there's also the function
socket(int,int,int) rename it to sth else :D
ahhh that just might be it, thank you, i'll let you know if it doesnt

This topic is closed to new replies.

Advertisement