Skip to content

Instantly share code, notes, and snippets.

@mash
Created November 4, 2014 09:59
Show Gist options
  • Save mash/a9c7839155532334609c to your computer and use it in GitHub Desktop.
Save mash/a9c7839155532334609c to your computer and use it in GitHub Desktop.
udp server sample using libuv
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uv.h"
#define CHECK(r, msg) \
if (r<0) { \
fprintf(stderr, "%s: %s\n", msg, uv_strerror(r)); \
exit(1); \
}
static uv_loop_t *uv_loop;
static uv_udp_t server;
static void on_recv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* rcvbuf, const struct sockaddr* addr, unsigned flags) {
if (nread > 0) {
printf("%lu\n",nread);
printf("%s",rcvbuf->base);
}
printf("free :%lu %p\n",rcvbuf->len,rcvbuf->base);
free(rcvbuf->base);
}
static void on_alloc(uv_handle_t* client, size_t suggested_size, uv_buf_t* buf) {
buf->base = malloc(suggested_size);
buf->len = suggested_size;
printf("malloc:%lu %p\n",buf->len,buf->base);
}
int main(int argc,char *argv[]) {
int status;
struct sockaddr_in addr;
uv_loop = uv_default_loop();
status = uv_udp_init(uv_loop,&server);
CHECK(status,"init");
uv_ip4_addr("0.0.0.0", 11000, &addr);
status = uv_udp_bind(&server, (const struct sockaddr*)&addr,0);
CHECK(status,"bind");
status = uv_udp_recv_start(&server, on_alloc, on_recv);
CHECK(status,"recv");
uv_run(uv_loop, UV_RUN_DEFAULT);
return 0;
}
LIBUV_HOME := $(HOME)/src/github.com/joyent/libuv
LIBUV := $(LIBUV_HOME)/build/Release/libuv.a
INC = $(LIBUV_HOME)/include
all:
gcc -o main -I$(INC) -Wall main.c $(LIBUV)
PHONY: all
@dam2k
Copy link

dam2k commented Sep 7, 2018

It's better to clean memory with bzero() after calling malloc() on on_alloc() callback, or directly use calloc(1, suggested_size), otherwise you'll risk to read unterminated string when you printf() on rcvbuf->base in on_recv() callback. This is a security and stability issue.
The rest of the file seems OK. Thank you.

@Phunkafizer
Copy link

Is there a way to get the IP address of the interface which received the frame in on_recv?

@kroggen
Copy link

kroggen commented Mar 31, 2019

You can use uv_ip4_name() on the returned addr parameter.

char sender[17] = { 0 };
uv_ip4_name((const struct sockaddr_in*) addr, sender, 16);
printf("Recv from %s\n", sender);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment