Created
September 13, 2018 20:44
-
-
Save lemoce/cf4e50c280b7e0605352c0d8126482eb to your computer and use it in GitHub Desktop.
example of libevent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://stackoverflow.com/questions/11990700/broken-pipe-epipe-on-connection-to-loopback-address/12068942#12068942 | |
*/ | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
/* Required by event.h. */ | |
#include <sys/time.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <err.h> | |
#include <assert.h> | |
#include <event2/event.h> | |
#include <event2/event_compat.h> | |
void on_connect(int sock, short ev, void *arg) | |
{ | |
assert(ev == EV_WRITE); | |
printf("got writeable on: %d\n", sock); | |
int optval = -1; | |
socklen_t optlen = sizeof(optval); | |
getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen); | |
assert(optval == 0); | |
printf("successfull asynchronous connect on: %d\n", sock); | |
event_loopbreak(); | |
} | |
void init_addr(struct sockaddr_in *addr, short port) | |
{ | |
memset(addr, '\0', sizeof(*addr)); | |
addr->sin_family = AF_INET; | |
addr->sin_port = htons(port); | |
addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
} | |
void setup_accept(int sock) | |
{ | |
int one = 1; | |
struct sockaddr_in addr; | |
init_addr(&addr, 9876); | |
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); | |
bind(sock, (struct sockaddr *)&addr, sizeof(addr)); | |
listen(sock, 1); | |
} | |
int complete_accept(int sock) | |
{ | |
struct sockaddr_in addr; | |
socklen_t addrlen = sizeof(addr); | |
return accept(sock, (struct sockaddr *)&addr, &addrlen); | |
} | |
int try_connect(int sock) | |
{ | |
struct sockaddr_in addr; | |
init_addr(&addr, 9876); | |
return connect(sock, (struct sockaddr *)&addr, sizeof(addr)); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int accept_sock = socket(PF_INET, SOCK_STREAM, 0); | |
setup_accept(accept_sock); | |
int client_sock = socket(PF_INET, SOCK_STREAM, 0); | |
fcntl(client_sock, F_SETFL, fcntl(client_sock, F_GETFL) | O_NONBLOCK); | |
printf("trying first connect on: %d\n", client_sock); | |
int r = try_connect(client_sock); | |
assert(r < 0 && errno == EINPROGRESS); | |
event_init(); | |
struct event_base *base = event_base_new(); | |
struct event *ev_connect; | |
ev_connect = event_new(base, client_sock, EV_WRITE, on_connect, 0); | |
event_add(ev_connect, 0); | |
int new_sock = complete_accept(accept_sock); | |
event_base_dispatch(base); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment