How to Get Sender IP from Incoming UDP Packet
Retrieving the sender’s IP address from an incoming UDP packet is a standard network programming task handled directly at the socket layer. Because UDP is a connectionless protocol, the receiving socket does not maintain an active connection with the client; instead, the underlying operating system inspects the IP header of each incoming datagram and exposes the source address via socket reading APIs. This guide demonstrates how to extract the sender’s IP address and port across several popular programming languages, including Python, Node.js, C, and Go.
Python
In Python, the built-in socket module provides the
recvfrom() method, which returns both the incoming data
buffer and a tuple containing the sender’s IP address and port
number.
import socket
# Create a UDP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', 8080))
print("Listening for incoming UDP packets on port 8080...")
while True:
# recvfrom returns (data, (sender_ip, sender_port))
data, (sender_ip, sender_port) = server_socket.recvfrom(1024)
print(f"Received message from {sender_ip}:{sender_port}")
print(f"Data: {data.decode('utf-8', errors='ignore')}")Node.js
Node.js uses the native dgram module to handle UDP
communication. When a message arrives, the 'message' event
provides an rinfo (remote info) object containing the
sender’s metadata.
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
// rinfo contains address, family, port, and size
const senderIp = rinfo.address;
const senderPort = rinfo.port;
console.log(`Received packet from ${senderIp}:${senderPort}`);
console.log(`Message: ${msg.toString()}`);
});
server.bind(8080, () => {
console.log('UDP server listening on port 8080');
});C (POSIX Sockets)
In C and C++, you pass a pointer to a sockaddr_in
structure into the POSIX recvfrom() system call. The kernel
fills this structure with the client’s information, which you convert
into a human-readable string using inet_ntop().
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[1024];
char sender_ip[INET_ADDRSTRLEN];
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(8080);
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
printf("Waiting for UDP packet on port 8080...\n");
ssize_t bytes_received = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0,
(struct sockaddr*)&client_addr, &client_len);
if (bytes_received >= 0) {
buffer[bytes_received] = '\0';
// Convert the binary IP address to a string
inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ip, INET_ADDRSTRLEN);
int sender_port = ntohs(client_addr.sin_port);
printf("Received packet from %s:%d\n", sender_ip, sender_port);
printf("Payload: %s\n", buffer);
}
close(sockfd);
return 0;
}Go
Go’s standard net package provides the
ReadFromUDP method on a *net.UDPConn instance.
This returns the number of bytes read and a *net.UDPAddr
struct containing the remote address.
package main
import (
"fmt"
"net"
)
func main() {
addr := net.UDPAddr{
Port: 8080,
IP: net.ParseIP("0.0.0.0"),
}
conn, err := net.ListenUDP("udp", &addr)
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Println("Listening for UDP packets on port 8080...")
buffer := make([]byte, 1024)
for {
// ReadFromUDP returns the number of bytes and the remote UDPAddr
n, remoteAddr, err := conn.ReadFromUDP(buffer)
if err != nil {
fmt.Println("Error reading:", err)
continue
}
senderIP := remoteAddr.IP.String()
senderPort := remoteAddr.Port
fmt.Printf("Received %d bytes from %s:%d\n", n, senderIP, senderPort)
fmt.Printf("Data: %s\n", string(buffer[:n]))
}
}