Casting a struct for sending to socket

This is a discussion on Casting a struct for sending to socket within the Networking/Device Communication forums, part of the General Programming Boards category; Hi Guys I am trying to send a struct to a UDP socket, but I'm not entirely sure how to ...

  1. #1
    Registered User
    Join Date
    Jan 2006
    Posts
    6

    Casting a struct for sending to socket

    Hi Guys

    I am trying to send a struct to a UDP socket, but I'm not entirely sure how to cast the structure.

    Code:
    struct CONNECT_REQUEST {
    	char headersize ;//	= 0x06;		//static EIB header size
    	char protocolversion;//	= 0x10;		//protocol version (1.0)
    	char servicetype[1];//	= 0x0205;	//service type in this case a connect_request
    	char totallength[1];//	= 0x0018;	//total length (24 byte)
    	char controllength;//	= 0x08;		//HPAI header for control endpoint
    	char protocoltype;//	= 0x01;		//0x01 UDP, 0x02 TCP
    	char IPcontrol[3];//;			//four chars for conrtol endpoint IP
    	char portcontrol[1];//			//two chars for control endpoint port must be gleaned during discovery
    	char datalength	;//	= 0x08;		//HPAI header length for data endpoint
    	char IPdata[3];	//			//fours chars for data endpoint IP use same IP as control endpoint
    	char portdata[1];//	= 0x0e57;	//set data port to 3671 default for EIB
    	char connectheader;//	= 0x02;		//connection type structue length
    	char connecttype;//	= 0x04;		//connection type in this case tunnelling may need 2 extra bytes.
    	};
    
    struct CONNECT_REQUEST connect;					//creat struct called connect of type CONNECT_REQUEST
    Code:
      /* construct CONNECT_REQUEST structure */
      connect.headersize		= 0x06;		//static EIB header size
      connect.protocolversion	= 0x10;		//protocol version (1.0)
      connect.servicetype[1]	= 0x02,0x05;	//service type in this case a connect_request
      connect.totallength[1]	= 0x00,0x18;	//total length (24 byte)
      connect.controllength		= 0x08;		//HPAI header for control endpoint
      connect.protocoltype		= 0x01;		//0x01 UDP, 0x02 TCP
      connect.IPcontrol[0] = oca, connect.IPcontrol[1] = ocb, connect.IPcontrol[2] = occ, connect.IPcontrol[2] = ocd;//set IP endpoint
      connect.portcontrol[0] = recv_str[12]&255, connect.portcontrol[13]&255;		//set port number for control endpoint
      connect.datalength		= 0x08;		//HPAI header length for data endpoint
      connect.IPdata[0] = oca, connect.IPdata[1] = ocb, connect.IPdata[2] = occ, connect.IPdata[3] = ocd;//set data end point IP
      connect.portdata[1]		= 0x0e,0x57;	//set data port to 3671 default for EIB
      connect.connectheader		= 0x02;		//connection type structue length
      connect.connecttype		= 0x04;		//connection type in this case tunneling 04
    
      if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)					//Creat UDP socket
    	DieWithError("UDP socket creation failed\n");
    
      /* construct UDP address structure */
      memset(&udp_addr, 0, sizeof(udp_addr));					//set udp_addr struct to 000's using memset
      udp_addr.sin_family      = AF_INET;						//set family type to AF_INET
      udp_addr.sin_addr.s_addr = htonl((oca,'.',ocb,'.',occ,'.',ocd));		//set address as any
      udp_addr.sin_port        = htons(mc_port);					//set the port as the same multi cast port
    
      if ((sendto(sock, &connect, sizeof(connect), 0, (struct sockaddr *) &udp_addr, sizeof(mc_addr))) != sizeof(connect)) 	//send data to socket
    	DieWithError("sendto() sent incorrect number of bytes");
    
      close(sock);
    
      exit(0);
    }
    This code compiles, but I get the error Invalid argument when sending to the socket. I have also tried casting to a pointer, but this gives an error when comilping.

    Any help would be greatly appreciated

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    Code:
    char servicetype[1];//	= 0x0205;	//service type in this case a connect_request
    char totallength[1];//	= 0x0018;	//total length (24 byte)
    ...
    char IPcontrol[3];//;			//four chars for conrtol endpoint IP
    ...
    char portcontrol[1];//			//two chars for control endpoint port must be gleaned during discovery
    ...
    char IPdata[3];	//			//fours chars for data endpoint IP use same IP as control endpoint
    char portdata[1];//	= 0x0e57;	//set data port to 3671 default for EIB
    Methinks you are off in your count a few places.
    Last edited by Dino; 04-08-2008 at 07:28 AM.
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  3. #3
    Registered User
    Join Date
    Jan 2006
    Posts
    6
    Code:
    char IPcontrol[3];		//four chars for conrtol endpoint IP
    char IPdata[3];			//fours chars for data endpoint IP use same IP as control endpoint
    char portdata[1];             //set data port to 3671 default for EIB
    because they are not strings i.e not terminated with \0 can I not just use the array elements [0].[1],[2] and [3]. giving me the 4 required characters.
    Last edited by chrisjmoss; 04-08-2008 at 07:41 AM.

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    In this case,
    Code:
    char IPcontrol[3];
    you are saying the array is 3 bytes long, plain and simple. If you want it to be 4 bytes long, code
    Code:
    char IPcontrol[4];
    I think you are confusing array length with array indexing. The highest element when indexing a 4 byte array is 3, as in:
    Code:
     
    IPcontrol[0] (the 1st element) 
    IPcontrol[1] (the 2nd element) 
    IPcontrol[2] (the 3rd element) 
    IPcontrol[3] (the 4th element)
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  5. #5
    Registered User
    Join Date
    Jan 2006
    Posts
    6
    Todd thanks for the help thus far, I was being a bit of a div and got confused with array size and indexing, but I have sorted that out now.

    Code:
    char servicetype[2];//	= 0x0205;	//service type in this case a connect_request
    	char totallength[2];//	= 0x0018;	//total length (24 byte)
    	char controllength;//	= 0x08;		//HPAI header for control endpoint
    	char protocoltype;//	= 0x01;		//0x01 UDP, 0x02 TCP
    	char IPcontrol[4];//;			//four chars for conrtol endpoint IP
    	char portcontrol[2];//			//two chars for control endpoint port must be gleaned during discovery
    	char datalength	;//	= 0x08;		//HPAI header length for data endpoint
    	char IPdata[4];	//			//fours chars for data endpoint IP use same IP as control endpoint
    	char portdata[2];//
    I'm still having having issues sending the structure with the sendto function do I need to cast from the structure or create a pointer to it.

    Code:
     struct CONNECT_REQUEST connect;					//creat struct called connect of type CONNECT_REQUEST
    
    if ((sendto(sock, &connect, sizeof(connect), 0, (struct sockaddr *) &udp_addr, sizeof(udp_addr))) != sizeof(connect)) 	//send data to socket
    	DieWithError("sendto() sent incorrect number of bytes");

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    "issues" is a bit vague. We have no error messages to work with here.
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,551
    > connect.portdata[1] = 0x0e,0x57;
    Also, the comma operator does not incrementally assign each value to each successive array element.

    Also, check that your struct is actually the size you want.
    Using a struct like this to communicate with an external API is generally non-portable.

    Code:
    unsigned char message[SOME_SIZE];
    message[MSG_HEADER_SIZE] = 0x06;
    message[MSG_PROTOCOL]    = 0x10;
    message[MSG_SERVICE_LSB] = 0x05;
    message[MSG_SERVICE_MSB] = 0x02;
    // and so on
    Tedious to be sure, but it's the only way to be sure of isolating yourself from padding, alignment and endian issues. Though TBH, a struct composed entirely of char should be OK.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. trying to send a struct over a socket
    By Anddos in forum C++ Programming
    Replies: 11
    Last Post: 06-27-2009, 02:56 PM
  2. Assignment HELP!!
    By cprogrammer22 in forum C Programming
    Replies: 35
    Last Post: 01-24-2009, 01:24 PM
  3. Looking for constructive criticism
    By wd_kendrick in forum C Programming
    Replies: 16
    Last Post: 05-28-2008, 09:42 AM
  4. Concatenating in linked list
    By drater in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 11:10 PM
  5. Binary Search Tree
    By penance in forum C Programming
    Replies: 4
    Last Post: 08-05-2005, 05:35 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21