LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-07-2021, 11:32 AM   #1
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Rep: Reputation: 4
UDP send


Hi,
Newbie here, the only knowledge I have is from googling.
Please bear with me.

How does one properly send data over UDP?
I have a data like this:

Code:
typedef union {
    struct {
        uint8_t buffer[BUFF_SIZE]; // 64
    } tx;

    struct {
        int32_t header;
        volatile int32_t Cmd[COMMAND_SIZE]; // 4
        float setPoint[VARIABLES]; // 6
        uint8_t enable;
        uint8_t outputs;
        uint8_t spar0;
        uint8_t spar1;
    } data;

} txData_t;

txData_t txData;
The header is always a fixed data.
Only header and enable has initial value greater than 0,
the rest are 0 values.
I'm sending the whole 64byte buffer over UDP, but I'm only receiving
the header, I'm expecting to also receive the enable value
but it's not there.
What do I need to do to make sure I receive the datas or for that matter
how do I make sure that the datas are actually getting sent.
 
Old 08-07-2021, 12:06 PM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,205
Blog Entries: 1

Rep: Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565
Guess your code looks like this:
Code:
txData *ptr;
struct sockaddr_in partner;
...
sendto (socket, ptr, sizeof ptr, (struct sockaddr *)&partner, sizeof partner);
Suggested fix:
Code:
sendto (socket, ptr, sizeof *ptr, (struct sockaddr *)&partner, sizeof partner);
PS: or similiar change with `recv`: instead of `sizeof pointer` use `sizeof *pointer` or `BUFF_SIZE`
 
Old 08-07-2021, 12:59 PM   #3
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
Hi thanks,

I'm actually using just send.
Code:
udpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
...
bzero((char*) &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET; // IPv4
server_addr.sin_port = htons(UDP_PORT);
server_addr.sin_addr.s_addr = inet_addr(remoteAddress);

/* Connect to send and receive only to the server_addr */
ret = connect(udpSocket, (struct sockaddr*) &server_addr,
      sizeof(struct sockaddr_in));

//setup timeouts
...

// then send.
ret = send(udpSocket, txData.tx.buffer, BUFF_SIZE, 0);
...

ret = recv(udpSocket, rxData.rx.buffer, BUFF_SIZE, 0);
...
 
1 members found this post helpful.
Old 08-07-2021, 04:07 PM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,205
Blog Entries: 1

Rep: Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565
Do you have a rxData_t type?
 
Old 08-07-2021, 05:14 PM   #5
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
yes, I just didn't post it.
rxData is a different type/stucture
It belongs to the same code as txData on
the client side.

The other side, the server, where I receive is identical
typedef'ed union as the txData, but named rxData
since its the receiver.

Edit:
Ok maybe it's a bit confusing.

both sides has txData/rxData with identical structure
except it's name is the reverse. The structure of txData on the
client side is identical to server, just on the server side
it's named rxData. Same with the others.

Last edited by lokal1; 08-07-2021 at 05:20 PM.
 
Old 08-07-2021, 11:54 PM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,205
Blog Entries: 1

Rep: Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565
I think it would be the right time to read this:
https://stackoverflow.com/help/minim...ucible-example
 
Old 08-08-2021, 05:23 AM   #7
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
Thanks for the patience.
This is basically it. My recieving end is similar.
Code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define COMMAND_SIZE   4
#define VARIABLES      6
#define BUFF_SIZE      64

#define UDP_PORT        20218
#define SEND_TIMEOUT_US 1000
#define RECV_TIMEOUT_US 1000

static const char *remoteAddress = "127.0.0.1";

typedef union {
    struct {
        uint8_t buffer[BUFF_SIZE];
    } tx;

    struct {
        int32_t header;
        int32_t Cmd[COMMAND_SIZE];
        float setPoint[VARIABLES];
        uint8_t enable;
        uint8_t outputs;
        uint8_t spar0;
        uint8_t spar1;
    } data;

} txData_t;


typedef union {
    struct {
        uint8_t buffer[BUFF_SIZE];
    } rx;

    struct {
        int32_t header;
        int32_t Feedback[COMMAND_SIZE];   
        float processVariable[VARIABLES]; 
        uint8_t inputs;
    } data;

} rxData_t;


rxData_t rxData;
txData_t txData;


int main() {
  int ret;
  int udpSocket;
  struct sockaddr_in server_addr;

  udpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (udpSocket < 0) {
    printf("ERROR: can't open socket: %s\n", strerror(errno));
    return -errno;
  }

  bzero((char*) &server_addr, sizeof(server_addr));
  server_addr.sin_family = AF_INET; // IPv4
  server_addr.sin_port = htons(UDP_PORT);
  server_addr.sin_addr.s_addr = inet_addr(remoteAddress);

  /* Connect to send and receive only to the server_addr */
  ret = connect(udpSocket, (struct sockaddr*) &server_addr,
      sizeof(struct sockaddr_in));

  if (ret < 0) {
    printf("ERROR: can't connect: %s\n", strerror(errno));
    return -errno;
  }

  struct timeval timeout;
  timeout.tv_sec = 0;
  timeout.tv_usec = RECV_TIMEOUT_US;

  ret = setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout,
      sizeof(timeout));
  if (ret < 0) {
    printf("ERROR: can't set receive timeout socket option: %s\n",
        strerror(errno));
    return -errno;
  }

  timeout.tv_usec = SEND_TIMEOUT_US;
  ret = setsockopt(udpSocket, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout,
      sizeof(timeout));
  if (ret < 0) {
    printf("ERROR: can't set send timeout socket option: %s\n",
        strerror(errno));
    return -errno;
  }
  
  for(int i=0; i<sizeof(txData.tx.buffer); i++) {
  	txData.tx.buffer[i] = 0;
  }
  
	txData.data.header = 0x77726974;
	txData.data.enable = 0x07;

  ret = send(udpSocket, txData.tx.buffer, BUFF_SIZE, 0);
  if (ret < 0) {
    printf("ERROR: Unable to send: %s\n", strerror(errno));
  }else{
  	printf("Data sent %d\n", ret);
  }
/*
  ret = recv(udpSocket, rxData.rx.buffer, BUFF_SIZE, 0);
  if (ret < 0) {
    printf("ERROR: Unable to receive: %s\n", strerror(errno));
  }else{
  	printf("Data received %d\n", ret);
  }
*/ 
  
  close(udpSocket);
}
I have just tested it with a simulated server on my PC,
(the actual server is a microcontroller).
Learnt a bit of wireshark, I just found out that in the
(hex view) packet bytes the value '7' is there. Since it's a not printable
value, it's not in the packet details?
I'll investigate further, if you have more input that would be great.
 
Old 08-08-2021, 10:33 AM   #8
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,205
Blog Entries: 1

Rep: Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565Reputation: 1565
You cannot read the 'enable' field from the 'rxData_t' structure, because it doesn't have such a field. You can find it out if you add more debug-print into your program. Example attached.
Attached Files
File Type: txt r.c.txt (1.6 KB, 15 views)

Last edited by NevemTeve; 08-08-2021 at 10:36 AM.
 
Old 08-08-2021, 11:25 AM   #9
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora 33
Posts: 3,640

Rep: Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055
You should verify that you receive BUFF_SIZE bytes before looking at the contents.
 
Old 08-08-2021, 12:05 PM   #10
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
Thanks Guys/Gals,

The txData/rxData in the posted code is just for the client.
The server also has the txData/rxData. The rxData union of
the server is identical to the txData of the client same
as the txData of the server is identical to rxData of the client.

I've verified the received bytes. It says 64bytes so
I'm getting all the bytes just not sure why not the correct bytes.
If I'm seeing it in wireshark it's being sent, I'll have a
second look at the receiving end.

Thanks again.
 
Old 08-08-2021, 01:23 PM   #11
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora 33
Posts: 3,640

Rep: Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055Reputation: 1055
Are both machines the same architecture?
 
2 members found this post helpful.
Old 08-08-2021, 05:42 PM   #12
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
'figured it out. I wasn't clearing the DMA transfer complete flag.
The client is a RaspberryPi, talking to an STM32F4.
I believe the Rpi can do both endian, but the micro is definitely little ender.

Thanks guys.or gals.

Edit:

How does one make this thread solved?

Last edited by lokal1; 08-08-2021 at 05:43 PM.
 
Old 08-09-2021, 07:19 AM   #13
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,047

Rep: Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074Reputation: 4074
Quote:
Originally Posted by lokal1 View Post
How does one make this thread solved?
"Thread tools" pull down menu, towards the top of the page.
 
1 members found this post helpful.
Old 08-09-2021, 01:14 PM   #14
lokal1
LQ Newbie
 
Registered: Jul 2006
Distribution: Artix
Posts: 25

Original Poster
Rep: Reputation: 4
Thanks.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
iptables -p udp and -m udp Shwick Linux - Networking 1 10-22-2008 07:44 PM
uknown url type udp when using a udp tracker fakie_flip Linux - Software 1 08-03-2006 05:03 AM
UDP: Short Packets: and UDP bad checksum: entries in dmesg minutes2memories Linux - Networking 2 02-26-2006 07:28 PM
RFC 868 udp 37 time-udp gpl SUSE / openSUSE 2 03-31-2005 10:07 AM
How to receive UDP and ICMP packets, by one UDP socket(PMTUD) myself_rajat Linux - Networking 0 05-28-2004 05:43 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:20 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration