11011100
11011100

Reputation: 125

Program does not send UDP package on specified port

I'm new to socket programming. I want to send a UDP package to a specific port on another PC in the network. When I analysie my network traffic with Wireshark I see a different port number in the outgoing packages from what I specified in my code. With port=10000 the actual port it gets send to is 4135. When I changed it to port=15000 (just to try something different) it got send to port 38970.

The port numbers wireshark shows must be true, as a receiving program set to listen on these ports (4135 or 38970) does react to sent packages, although the received data seems like garble (the console shows unknown characters, the debug console shows "1\355I\211\321^H\211...").

Any ideas why?

I'm running this on a Debian VM connected to other VMs in a virtual network. A very similar program using TCP worked just fine.

#include <sys/types.h>      //Various types, including ssize_t
#include <sys/socket.h>     //Types, macros and functions for sockets
#include <netinet/in.h>     //Types, including sockaddr_in, macros
#include <arpa/inet.h>      //Types and functions, including inet_aton()
#include <unistd.h>         //Types, macros and functions for Unix/Posix
#include <stdlib.h>         //GP types, macros and functions
#include <stdio.h>          //IO operations (streams)
#include <string.h>         //Functions for string operations
 
#define BC_ADDR "192.168.1.255"
 
int main(int argc, char** argv) {
    int                 clientSocket;
    const int           setBroadcast = 1;
    in_port_t           port = 10000;
    struct sockaddr_in  broadcastAddr;
    int                 broadcastAddrLen = sizeof(struct sockaddr_in);
    const char*         msg = "Hello World";
 
    //Create a new UDP socket
    clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if(clientSocket > 0) {
        printf("Socket created successfully\n");
    }
    else {
        printf("Failure during socket creation\n");
        exit(EXIT_FAILURE);
    }
 
    //Set socket options to allow broadcasts
    int setSockOptStatus = setsockopt(clientSocket, SOL_SOCKET, 
        SO_BROADCAST, &setBroadcast, sizeof(setBroadcast));
    if(setSockOptStatus != 0) {
        printf("Error setting socket options!");
        close(clientSocket);
        return EXIT_FAILURE;
    }
 
    //Form boradcast address structure
    broadcastAddr.sin_family = AF_INET;
    broadcastAddr.sin_port   = port;
    broadcastAddr.sin_addr.s_addr = inet_addr(BC_ADDR);
 
    //Send broadcast message
    sendto(clientSocket, msg, strlen(msg)+1, 0, 
           (struct sockaddr*) &broadcastAddr, broadcastAddrLen);
 
    //Close socket and exit program
    close(clientSocket);
    return EXIT_SUCCESS;    
}

Upvotes: 0

Views: 515

Answers (1)

dbush
dbush

Reputation: 225227

The problem is how you're setting the port:

broadcastAddr.sin_port   = port;

The IP address and port number stored in a struct sockaddr_in must both be in network byte order which is big-endian byte ordering, i.e. most significant byte first. Your machine apparently uses little-endian byte ordering, i.e. least significant byte first, so by assigning the port number directly to the sin_port member that conversion is not being done.

This is more apparent if you look at the hexadecimal representation of the expected and actual port numbers:

  • 10000d = 2710h, 4135d = 1027h
  • 15000d = 3a98h, 38970 = 983ah

You need to call the htons() function, which converts a 16-bit value from host byte order to network byte order:

broadcastAddr.sin_port   = htons(port);

Upvotes: 3

Related Questions