[SOLVED] problem receiving UDP packets with C, on openSuse
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am trying to receive an UDP packet from a device. I know the IP-adres of this device and the port number it is sending the packets to. When I use the code below (example linux howtos) and change the ports it doesn't receive anything.
Code:
/* Creates a datagram server. The port
number is passed as an argument. This
server runs forever */
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sock, length, n;
socklen_t fromlen;
struct sockaddr_in server;
struct sockaddr_in from;
char buf[1024];
if (argc < 2) {
fprintf(stderr, "ERROR, no port provided\n");
exit(0);
}
sock=socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) error("Opening socket");
length = sizeof(server);
bzero(&server,length);
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(atoi(argv[1]));
if (bind(sock,(struct sockaddr *)&server,length)<0)
error("binding");
fromlen = sizeof(struct sockaddr_in);
while (1) {
n = recvfrom(sock,buf,1024,0,(struct sockaddr *)&from,&fromlen);
if (n < 0) error("recvfrom");
write(1,"Received a datagram: ",21);
write(1,buf,n);
n = sendto(sock,"Got your message\n",17,
0,(struct sockaddr *)&from,fromlen);
if (n < 0) error("sendto");
}
return 0;
}
When I use the example for the client it does receive.
I don't really know how the device sends the packets, I just know to what port and what IP adres it has.
What do I have to change to receive the packets ??
thanks in advance,
Mike.
Last edited by Beelz; 10-05-2011 at 08:12 AM.
Click here to see the post LQ members have rated as the most helpful post in this thread.
I am trying to receive an UDP packet from a device. I know the IP-adres of this device and the port number it is sending the packets to. When I use the code below (example linux howtos) and change the ports it doesn't receive anything.
The code you posted is for a server, hence the reason for the call to bind(). How can you be sure that the device is sending packets to the system where this code is running? You have chosen INADDR_ANY, which means that all network interfaces (e.g. eth0 and lo), will be used to bind to your specified port to your socket.
If the device is sending datagrams to your system's IP address and port, then you should receive them. If the device is sending to some other IP address and/or port, then you won't receive a thing.
Please confirm that the device is configured properly.
First of all, for a good tutorial with example code that works, start with Beej's Guide to Network Programming. Second, when testing networking code, use netcat (nc) to confirm that the connection actually works, before you try it on your own code. When you've got it to work with netcat, then try it on your own code. netcat can be a working server or client (or both, if that makes sense), and when confronted with the problem of not knowing whether your server code or your client code or your network doesn't work, it helps to remove one or more of the unknowns in the equation. Once you've done that, run your code under a debugger, like gdb, or one of it's GUI versions like ddd.
Using netcat and wireshark I found out that the device is sending its datagrams to an internal IP adres of 224.0.23.12 instead of my IP adres (where the request is coming from) 192.168.10.111
I guess I have to find a way to change the reply IP adres of the device, for that I will contact the supplier.
Using netcat and wireshark I found out that the device is sending its datagrams to an internal IP adres of 224.0.23.12 instead of my IP adres (where the request is coming from) 192.168.10.111
I guess I have to find a way to change the reply IP adres of the device, for that I will contact the supplier.
Thanks for the help,
Mike.
That's a multicast group IP address.
Here's an example of how I would setup a client to send to that IP address:
Code:
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
unsigned char ttl = 1; // time to live
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
When you send data, use sendto() using a sockaddr_in object in which you specify the multicast group IP (e.g. 224.0.23.12), and of course the port number, of where the device is using.
If the device is acting as a client, then you need to set up a server; then something like this is in order:
Code:
const char* MULTICAST_GROUP = "224.0.23.12";
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
unsigned char enable = 0;
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &enable, sizeof(enable));
memset(&server, 0, length);
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(atoi(argv[1]));
bind(sock, (struct sockaddr *)&server, length);
// proceed to receive, similar to what you have implemented before...
P.S. The following may be helpful:
Code:
The following is borrowed (w/o permission!) from: Antony Courtney (antony@scrg.cs.tcd.ie)
Notes about Multicasting:
Multicast Addresses are restricted to the following ranges:
224.0.0.0 to 239.255.255.255
although some of these addresses are reserved for multicasting routing information.
Applications should not use these reserved addresses, which are:
224.0.0.0 to 224.0.0.255
Time-to-Live (TTL) for Multicast Packets are by default restricted to the current
subnet (TTL=1). Below are the supported multicast TTL thresholds:
0 restricted to the same host
1 restricted to the same subnet (default)
32 restricted to the same site
64 restricted to the same region
128 restricted to the same continent
255 unrestricted
The TTL can be changed using setsockopt(). For example:
unsigned char ttl = 32;
setsockopt(sock.GetSocketDesc(), IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
Last edited by dwhitney67; 10-06-2011 at 05:42 AM.
I think you are confusing the matter, and I know I'm confused from what you have stated.
You said you had a device on your local subnet that is issuing message(s), and that you have verified this via wireshark. You even went as far as to indicate that the device is using a multicast IP address. You stated that you know the port that this device is sending to as well.
If your device is acting as the server, then all you need to do is develop a client that communicates on the multicast IP address and port. The server will respond to the client via the client's IP address/port.
If your device is pumping out messages on the multicast IP, then I would suggest that you attempt to collect those messages using a client application.
Last edited by dwhitney67; 10-07-2011 at 06:44 AM.
I used a client to test if the code worked, an example client is given by dwhitney67 above this post.
If the code is correct you will see the datagrams printed in the konsole.
If you use a client and server on the same computer it will work fine,
For my device to work (connected to network) I had to turn off the firewall.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.