2019-02-22 15:01:22 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include "evt_core.h"
|
|
|
|
#include "net_tools.h"
|
|
|
|
|
|
|
|
int on_udp(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
|
|
|
char buffer[1500];
|
|
|
|
ssize_t nread, nwritten;
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
socklen_t addrlen = sizeof(addr);
|
|
|
|
|
|
|
|
nread = recvfrom(fdinfo->fd, buffer, sizeof(buffer), MSG_TRUNC, (struct sockaddr*)&addr, &addrlen);
|
|
|
|
if (nread == -1 && errno == EAGAIN) return 1; // Read done
|
|
|
|
if (nread <= 0 || nread > sizeof(buffer)) {
|
|
|
|
fprintf(stderr, "Message is either truncated or an error occured. nread=%ld\n", nread);
|
|
|
|
perror("read errno");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
nwritten = sendto(fdinfo->fd, buffer, nread, 0, (struct sockaddr*)&addr, addrlen);
|
|
|
|
// @FIXME don't support EAGAIN on write. Could be intended, you don't think so?
|
|
|
|
if (nwritten != nread) {
|
|
|
|
fprintf(stderr, "Didn't write the same number of bytes as read. nread=%ld, nwritten=%ld\n", nread, nwritten);
|
|
|
|
perror("write errno");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
2019-03-06 16:12:58 +00:00
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
2019-02-22 15:01:22 +00:00
|
|
|
printf("~ udpecho ~\n");
|
|
|
|
|
|
|
|
int opt, udp_sock, verbose = 0;
|
|
|
|
char *port = NULL;
|
|
|
|
struct evt_core_ctx evts = {0};
|
|
|
|
|
|
|
|
// 1. Parse parameters
|
|
|
|
while ((opt = getopt(argc, argv, "p:v")) != -1) {
|
|
|
|
switch(opt) {
|
|
|
|
case 'v':
|
2019-04-01 12:16:41 +00:00
|
|
|
verbose++;
|
2019-02-22 15:01:22 +00:00
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
port = optarg;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto usage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. Register category
|
|
|
|
struct evt_core_cat udp_read = {
|
|
|
|
.app_ctx = NULL,
|
|
|
|
.free_app_ctx = NULL,
|
|
|
|
.cb = on_udp,
|
|
|
|
.err_cb = NULL,
|
|
|
|
.name = "udp-read",
|
|
|
|
.flags = EPOLLIN | EPOLLET,
|
|
|
|
.socklist = NULL
|
|
|
|
};
|
2019-04-01 12:16:41 +00:00
|
|
|
evt_core_init(&evts, verbose);
|
2019-02-22 15:01:22 +00:00
|
|
|
evt_core_add_cat(&evts, &udp_read);
|
|
|
|
|
|
|
|
// 3. Register UDP socket
|
|
|
|
udp_sock = create_udp_server ("127.0.0.1", port);
|
|
|
|
|
|
|
|
char url[1024];
|
|
|
|
struct evt_core_cat cat = {0};
|
|
|
|
struct evt_core_fdinfo fdinfo = {0};
|
|
|
|
fdinfo.cat = &cat;
|
|
|
|
fdinfo.url = url;
|
|
|
|
|
|
|
|
fdinfo.fd = udp_sock;
|
|
|
|
sprintf(url, "udp:rw:127.0.0.1:%s", port);
|
|
|
|
fdinfo.cat->name = "udp-read";
|
|
|
|
evt_core_add_fd(&evts, &fdinfo);
|
|
|
|
|
|
|
|
// 4. Start main loop
|
|
|
|
evt_core_loop (&evts);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
usage:
|
|
|
|
fprintf(stderr, "Usage: %s -p <port> [-v]\n", argv[0]);
|
|
|
|
}
|