Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Below is a simple <code>libevent</code> toy program that synthesizes <code>EINPROGRESS</code>, and then waits for the connection to complete by waiting for <code>EV_WRITE</code>. Basically, this program shows that in your application, you should attempt to do the <code>connect</code> call first, and if it fails with <code>EINPROGRESS</code>, you should wait for completion before performing I/O.</p> <p>This is the <code>libevent</code> callback function:</p> <pre><code>extern "C" void on_connect (int sock, short ev, void *arg) { assert(ev == EV_WRITE); std::cout &lt;&lt; "got wrieable on: " &lt;&lt; sock &lt;&lt; '\n'; int optval = -1; socklen_t optlen = sizeof(optval); getsockopt(sock, SOL_SOCKET, SO_ERROR, &amp;optval, &amp;optlen); assert(optval == 0); std::cout &lt;&lt; "succesful asynchronous connect on: " &lt;&lt; sock &lt;&lt; '\n'; event_loopbreak(); } </code></pre> <p>These are some helper functions used by the toy application:</p> <pre><code>static void init_addr (struct sockaddr_in *addr, short port) { memset(addr, '\0', sizeof(*addr)); addr-&gt;sin_family = AF_INET; addr-&gt;sin_port = htons(port); addr-&gt;sin_addr.s_addr = htonl(INADDR_LOOPBACK); } static void setup_accept (int sock) { const int one = 1; struct sockaddr_in addr; init_addr(&amp;addr, 9876); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &amp;one, sizeof(one)); bind(sock, (struct sockaddr *)&amp;addr, sizeof(addr)); listen(sock, 1); } static int complete_accept (int sock) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); return accept(sock, (struct sockaddr *)&amp;addr, &amp;addrlen); } static int try_connect (int sock) { struct sockaddr_in addr; init_addr(&amp;addr, 9876); return connect(sock, (struct sockaddr *)&amp;addr, sizeof(addr)); } </code></pre> <p>And the <code>main</code> program is below:</p> <pre><code>int main () { int accept_sock = socket(PF_INET, SOCK_STREAM, 0); setup_accept(accept_sock); int sock = socket(PF_INET, SOCK_STREAM, 0); fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK); std::cout &lt;&lt; "trying first connect on: " &lt;&lt; sock &lt;&lt; '\n'; int r = try_connect(sock); assert(r &lt; 0 &amp;&amp; errno == EINPROGRESS); event_init(); struct event ev_connect; event_set(&amp;ev_connect, sock, EV_WRITE, on_connect, 0); event_add(&amp;ev_connect, 0); int new_sock = complete_accept(accept_sock); event_dispatch(); return 0; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload