Skip to content

Instantly share code, notes, and snippets.

@lemoce
Created September 13, 2018 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lemoce/cf4e50c280b7e0605352c0d8126482eb to your computer and use it in GitHub Desktop.
Save lemoce/cf4e50c280b7e0605352c0d8126482eb to your computer and use it in GitHub Desktop.
example of libevent
/*
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