Thread: Send a C Struct by UDP Socket C#

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184

    Send a C Struct by UDP Socket C#

    I Need connect to a host using UDP Sockets, but i have to send a packet with a struct format.

    Somebody have any Idea... ? (sorry for my english)

    Code:
    /* Packet structure */
    struct packet {
    	uint32_t seq;
    	uint8_t data[IO_BUF_MAX];
    };
    Code:
    int udp_to_ssc_task(struct udp_pcb * udp, uthread_id_t id)
    {
    	struct packet pkt;
    	struct fox_system * sys = &fox_sys;
    	int next_seq, recv_err, pkt_size;
    	int n;
    
    	printf(" - %s: started.\n", __FUNCTION__);
    
    	pkt_size = sizeof(pkt.seq)+sys->out_data_size;
    
    	for (;;) {
    		/* stay here while a connection is not established */
    		while (!connected) {
    			uthread_sleep(10);
    		}
    
    		/* reset counters */
    		next_seq = 1;
    		recv_err = 0;
    
    		while (connected) {
    			/* receive data from udp conn */
    			if ((n = udp_recv(udp, &pkt, pkt_size, NULL)) < 0) {
    				/* rcv failed */
    				fprintf(stderr, "%s: udp_recv() fail!\n", __FUNCTION__);
    				break;
    			}
    			// adicionado por sérgio m.
    			putchar('r');
    
    			/* signal to monitor task that connection still established */
    			uthread_mutex_lock(mutex1);
    			uthread_cond_signal(rcving);
    			uthread_mutex_unlock(mutex1);
    
    			/* verify packet sequence field */
    			if (pkt.seq != next_seq) {
    				putchar('e');
    
    				next_seq = pkt.seq+1;
    				recv_err++;
    
    				/* max allowed errors occured, lose the connection */
    				if (recv_err > MAX_RECV_ERRORS) {
    					fprintf(stderr, "%s: connection lost!\n", __FUNCTION__);
    					connected = 0;
    					break;
    					}
    
    				continue;
    			}
    
    			/* consider consecutive errors */
    			recv_err = 0;
    
    			//show_packet(&pkt, n-sizeof(pkt.seq));
    			//printf("\r%d/%d", recv_err, recv_cnt);
    
    			/* synchonize rcvd data with outputs */
    			//fox_out_sync(pkt.data, sys->out_data_size);
    			
    			/* update counter */
    			next_seq++;
    		}
    	}
    
    	return 0;
    }

  2. #2
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Well you can export your c++ code into a c++ dll and setup proper marshalling in order to platform invoke this call. Other then that use a MemoryStream and a BinaryWriter to write out your packet to memory and then send it via one of the .NET socket classes.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    and if try to convert this to bytes and send...?

  4. #4
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Well, keep your 4 byte int for the sequence number, write that out, also keep a byte array of the appropriate size and write it out to the stream.

    You can also create a byte array thats IO_BUF_MAX + 4 size, and use BitConverter to place the appropriate bytes.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    sorry, can u exemplify this....
    Im confused...

  6. #6
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Roughly

    Code:
                //...
                const int PACKET_SIZE = 64;
                //...
                int nSequenceNumber = 22;
                byte[] OutputData = new byte[PACKET_SIZE - 4];
                //...
                using (MemoryStream MS = new MemoryStream())
                {
                    using (BinaryWriter BR = new BinaryWriter(MS))
                    {
                        BR.Write(nSequenceNumber);
                        BR.Write(OutputData);
    
                        MS.Capacity = PACKET_SIZE;
                        byte[] OutputStream = MS.GetBuffer();
                        //Send OutputStream
                    }
                }

  7. #7
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Thank's for ur help!

    Now i changed the code to get bytes from string, and create packet.

    Please, can u check this code... ?

    Code:
    const int PACKET_SIZE = 64;
    
            public void CreatePacket (int nSequenceNumber, string strMessage, ref byte[] OutputStream)
            {
                int OUTPUT_SIZE;
                //
                OUTPUT_SIZE = PACKET_SIZE - 4;
                //
                byte[] OutputData = new byte[OUTPUT_SIZE];
                OutputData = Encoding.ASCII.GetBytes(strMessage);
                //...
                using (MemoryStream MS = new MemoryStream())
                {
                    using (BinaryWriter BR = new BinaryWriter(MS))
                    {
                        BR.Write(nSequenceNumber);
                        BR.Write(OutputData);
    
                        MS.Capacity = PACKET_SIZE;
                        //byte[] OutputStream = MS.GetBuffer();
                        OutputStream = MS.GetBuffer();
                    }
                }
            }
    Code:
    /* Packet structure */
    struct packet {
    	uint32_t seq;
    	uint8_t data[IO_BUF_MAX];
    };

  8. #8
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Looks fine to me. Maybe I should also point out that all the //... I had were to emphasize that my hard coded values would probably be filled in by some other mechanism. They are not needed in the code.

    Did you try building and running it? At the very least you can set a breakpoint at OutputStream = MS.GetBuffer(), and check to make sure the array is what you expected.

  9. #9
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    I Have to send a uint32_t seq to identify the sequence number of packet.

    using this function to send a int: BR.Write(nSequenceNumber);

    this send a correct byte waited for the socket ?

    Code:
    int OUTPUT_SIZE;
                
                OUTPUT_SIZE = PACKET_SIZE - 4;
                //
                try
                {
                    UdpClient udpClient = new UdpClient(1234);
                    udpClient.Connect("10.0.0.80", 1234);
    
                    Byte[] sendBytes = new Byte[OUTPUT_SIZE];
    
                    CreatePacket(1, "TESTE1", ref sendBytes);
                    udpClient.Send(sendBytes, sendBytes.Length);

  10. #10
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    My C function to send a correct packet,
    I need Translate this to C#

    Code:
    int udp_send_proc(int fd)
    {
    	struct packet pkt_out;
    	uint32_t next_seq;
    
    	printf(" - %s: started.\n", __FUNCTION__);
    
    	for (;;) {
    		while (!connected) {
    			usleep(10);
    		}
    
    		next_seq = 1;
    
    		sleep(1);
    		printf("sending\n");
    
    		while (connected) {
    			pkt_out.seq = next_seq++;
    
    			pkt_out.data[0] = (uint8_t) ((next_seq) & 0xff) ;
    			pkt_out.data[1] = (uint8_t) ((next_seq+1) & 0xff) ;
    			pkt_out.data[2] = (uint8_t) ((next_seq+2) & 0xff) ;
    			pkt_out.data[3] = (uint8_t) ((next_seq+3) & 0xff) ;
    
    			send(fd, &pkt_out, sizeof(pkt_out.seq)+OUTPUT_SIZE, 0);
    			usleep(200);
    		}
    	}
    
    	return 0;
    }

  11. #11
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184

    Translate C to C#

    Code:
    struct packet {
    	uint32_t seq;
    	uint8_t data[16];
    };
    
    //........
    struct packet pkt_out;
    uint32_t next_seq;
    
    next_seq = 1;
    
    // ..............
    
    while (connected) {
    	pkt_out.seq = next_seq++;
    
    	pkt_out.data[0] = (uint8_t) ((next_seq) & 0xff) ;
    	pkt_out.data[1] = (uint8_t) ((next_seq+1) & 0xff) ;
    	pkt_out.data[2] = (uint8_t) ((next_seq+2) & 0xff) ;
    	pkt_out.data[3] = (uint8_t) ((next_seq+3) & 0xff) ;
    
    	send(fd, &pkt_out, sizeof(pkt_out.seq)+OUTPUT_SIZE, 0);
    I Need create this struck in C#, and send this data equal this C function.

    Sorry for not post this in C# Board.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Threads merged.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can I bind a UDP socket to a port, but send to any other port?
    By trillianjedi in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-25-2009, 04:27 PM
  2. sending n no of char data uning send() function,
    By thebrighter in forum Windows Programming
    Replies: 1
    Last Post: 08-22-2007, 12:26 PM
  3. Function validation.
    By Fhl in forum C Programming
    Replies: 10
    Last Post: 02-22-2006, 08:18 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. send zip file via socket
    By WaterNut in forum C Programming
    Replies: 11
    Last Post: 05-24-2005, 11:49 AM