Thread: UDP receiver not receiving packets

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    26

    UDP receiver not receiving packets

    Hi, I have 2 programs; UDP sender and receiver. These programs are absolutely basic, trying to get the concept and understand how it works. I specify the target IP and port via arguments in the sender, in the receiver I only specify the port number. The sender sends a message and waits for an ACK then exits. The receiver waits on recvfrom() and I do not understand why. I thought INADDR_ANY binded all interfaces to the program so any packet is received by it. Maybe I'm overlooking a syntax error, but I do not see why it isn't working. Here is the receiver code

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <strings.h>
    #include <netdb.h>
    #include <stdio.h>
    
    void error(char *msg)
    {
    	perror(msg);
    	exit(0);
    }
    		
    int main(int argc, char *argv[])
    {
    	int sock, length, fromlen, n;
    	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);
    	printf("Waiting to recv.\n"); fflush(stdout);
    
    	while (1) 
            {
    		n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *) &from, &fromlen);
    		if (n < 0) error("recvfrom");
    			
    		printf("Received a datagram.\n"); fflush(stdout);
    		printf("%s\n", buf); fflush(stdout);
    
    		n = sendto(sock, "Got your message\n", 17, 0, (struct sockaddr *) &from, fromlen);
    		if (n  < 0) error("sendto");
    	} // while
    
    	return(1);
     } // main
    Thanks for helping me debug!
    Chris

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by chris24300 View Post
    The receiver waits on recvfrom() and I do not understand why. I thought INADDR_ANY binded all interfaces to the program so any packet is received by it. Maybe I'm overlooking a syntax error, but I do not see why it isn't working.
    Using INADDR_ANY is fine, the problem is, you have not connect()ed anything. The precedure for the server is: bind a socket and wait for incoming connections using accept(); for the client: create a socket and call the server using connect().

    Your "sender/receiver" terminology covers up this misconception. With IP networking, they are called SERVER and CLIENT. Both of them can send() and recv(), but the client must initiate the relationship to the server. The server cannot initiate relationships (except with other servers) because a client cannot be connected to. A client connects, ie, the CLIENT must call a SERVER.
    Last edited by MK27; 08-21-2009 at 05:05 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    I think the whole point of UDP sockets is that you don't need to cennect(), listen() or accept() anything. Just bind() and then recvfrom().

    Maybe there's a problem with the client.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Thanks for helping me debug!
    Grab wireshark, so you can see what's going on along the wires.
    If you're not sure if anything is being sent, this will tell you.
    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.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by idelovski View Post
    I think the whole point of UDP sockets is that you don't need to cennect(), listen() or accept() anything. Just bind() and then recvfrom().
    Ah. Correct you are! I've only done stuff with TCP and thought all IP stuff was the same in this sense.

    Sorry.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Aug 2008
    Posts
    26
    @Salem: Thanks, I didn't think of that. I don't have the time but I'll check it out tomorrow morning and see what's being sent.

    idelovski, you mentioned there could be a problem with the client. When I compile I get two warnings:

    client_udp.c:52: warning: passing argument 5 of ‘sendto’ from incompatible pointer type
    client_udp.c:58: warning: passing argument 5 of ‘recvfrom’ from incompatible pointer type

    since the code satisfies the arguments in the man page I figured it wouldn't matter... It might, here is the client code.

    Code:
    void error(char *msg)
    {
    	perror(msg);
    	exit(0);
    } // error
    
    int main(int argc, char *argv[])
    {
    	int sock, length, n;
    	struct sockaddr_in server, from;
    	struct hostent *hp;
    	char buffer[256];
    	
    	if (argc != 3) 
    	{ 
    		printf("Usage: client <server IP> <port>\n");
    		exit(1);
    	}
    
    	sock = socket(AF_INET, SOCK_DGRAM, 0);
    	if (sock < 0) 
    		error("socket");
    	
    	///////////////////////////////////////
    	/* Specify Socket Info */
    	server.sin_family = AF_INET;			
    	server.sin_port = htons(atoi(argv[2]));		// port
    	server.sin_addr.s_addr = inet_addr(argv[1]);	// ip
    	///////////////////////////////////////
    	
    	length = sizeof(struct sockaddr_in);
    
    	printf("Please enter the message: ");
    	bzero(buffer, 256);
    	fgets(buffer, 255, stdin);
    
    	n = sendto(sock, buffer, strlen(buffer), 0, &server, length);
    	if (n < 0) 
    		error("Sendto");
    
    	printf("\nSent the message, waiting for response.\n"); fflush(stdout); 
    
    	n = recvfrom(sock, buffer, 256, 0, &from, &length);
    	if (n < 0) 
    		error("recvfrom");
    
    	printf("Got an ACK: %s", buffer); fflush(stdout); 
    } // main

  7. #7
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    Well, the code as it is works on my Mac.

    I had to include <stdlib.h> for the exit() and changed length type from int to socklen_t and I've put casts to (struct sockaddr *) to suppress those warnings, but aside from that, it all went well.

    $ ./srv 1234 &
    [1] 382
    $ Waiting to recv.

    $ ./clnt 127.0.0.1 1234
    Please enter the message: hallo

    Sent the message, waiting for response.
    Received a datagram.
    hallo

    Got an ACK: Got your message

  8. #8
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    The use of (struct sockaddr *) is what you're supposed to do.

    Your networking code, more or less, is fine. Your use of buffers... your server has a buffer overflow, and I suspect you have gaps in your knowledge regarding buffers, etc. Take this:
    Code:
             n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *) &from, &fromlen);
             if (n < 0) error("recvfrom");
     
             printf("Received a datagram.\n"); fflush(stdout);
             printf("%s\n", buf); fflush(stdout);
    When you recvfrom() a buffer, the return value, n here, is - on success - the number of bytes recv'd. You ignore this, and send that buffer to printf(). printf() excepts a string and specifically, a string should be null-terminated. recvfrom(), since it doesn't work with strings, doesn't guarentee that buf is null-terminated. Thus, you possibly cause buffer overflows when you pass this buffer to printf(), if the sender doesn't send a trailing null. (And worse, looking at your client code - you don't!)

    In short: Make sure your buffer is null terminated.
    The general form is this, if you want a string:
    Code:
    n = recvfrom(sock, buf, SIZE_OF_BUFFER - 1, 0, .....);
    // check n for errors
    buf[n] = 0; // null terminate that buffer.
    printf("%s\n", buf);
    This also worries me:
    Code:
         printf("Please enter the message: ");
         bzero(buffer, 256);
         fgets(buffer, 255, stdin);
    There is no real reason to call bzero() here. Further, your buffer sizes to bzero() and fgets() differ. If you real the man pages for both functions, you'll see that bzero() just zeros an area, and that fgets will put in a trailing null, so you can pass 256 to both functions.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  9. #9
    Registered User
    Join Date
    Aug 2008
    Posts
    26
    Thanks for all the responses! I'm still getting 'broken in' to linux and network programming, so please bare with me.

    When I run on lo (127.0.0.1) everything works fine. It's when I use different machines that the packet is lost somewhere.

    I am completely new to wireshark so I'll post what I think it beneficial. First off, I can ping both addresses and I can see the ICMP protocol is the only protocol that successfully reaches the destination. When I was capturing while running my programs I only get one captured message, i'll format as close as possible
    Code:
    No.    Time      Source         Destination      Protocol      Info
    1     0.000      10.0.0.X        10.0.0.X          UDP         Source port: 33267 Destination port: search-agent
    #      1947.3    10.0.0.X        10.0.0.X         ICMP         Echo (ping) reply
    I don't know what the UDP info means, is it searching for the port/host? The addresses are 2 devices that can communicate between one another over the air, they are not the IP of my machines. Not sure what to do now... Can I send messages in IMCP?

    Thanks,
    Chris
    Last edited by chris24300; 08-24-2009 at 09:59 AM.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    TCP and UDP (what you asked for with SOCK_DGRAM) are the two common data transport protocols.
    ICMP is one of the many control protocols which enable the whole shebang to work.

    > It's when I use different machines that the packet is lost somewhere.
    Check your various firewall logs to see if requests are being blocked.
    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.

  11. #11
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    Try with port 7. It is echo port and should be allowed.

  12. #12
    Registered User
    Join Date
    Aug 2008
    Posts
    26
    How many logs are there? I only know of the log in /var/log/messages. I just tried a sample send/receive UDP(straight from a book) using my actual machines, not external devices. The results were the same, nothing. So I should have started from step 1.

    I'm about to check through the router, but if the problem does not lie there then what else can cause this blockage? I started reading on the iptables so that's where I'm looking next. Are there other programs I should look at also?

  13. #13
    Registered User
    Join Date
    Aug 2008
    Posts
    26
    OK now i'm really confused. I changed which computers I used as the sender/receiver and everything works perfect....

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by chris24300 View Post
    OK now i'm really confused. I changed which computers I used as the sender/receiver and everything works perfect....
    Were you using LAN addresses (192.168...) or live inet addresses? Getting to a computer connected to a router "as if it were a server" *might* not be as simple as using the assigned IP address.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Registered User
    Join Date
    Aug 2008
    Posts
    26
    No, i used both the device IP (10.0.0.X) and my actual computer IPs. For some reason the destination port is lost when I'm on that specific machine as shown in my wireshark post previously.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with UDP
    By AlexS in forum C# Programming
    Replies: 0
    Last Post: 07-07-2009, 06:21 PM
  2. Sending / Receiving Info Via TCP or UDP
    By bengreenwood in forum C Programming
    Replies: 0
    Last Post: 03-24-2009, 02:17 AM
  3. simultaneously waiting for data on FIFO and UDP using select call
    By yogesh3073 in forum Networking/Device Communication
    Replies: 2
    Last Post: 01-05-2007, 09:53 AM
  4. UDP and TCP packets on port 6112
    By biosninja in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 01-19-2004, 11:21 AM