Example unix socket echo server

Horacio Sanson hsanson at gmail.com
Tue Nov 2 08:26:12 CET 2010

On Tuesday 02 November 2010 13:44:58 AJ ONeal wrote:
> I believe that I've done this Unix Socket Echo Server "the right way" now:
> http://github.com/coolaj86/libev-examples/blob/master/unix-echo.c
> The question that I have is if it's true to say that a unix socket is
> writable whenever it is readable?

no it is not.

> When I tried listening for when it was writable, it seemed to fire the
> event over and over again.
> I didn't think that was particularly helpful.

Libev is Level-Triggered that means that as long as the socket write buffer has 
space you will keep getting the write event. You can read the man page of 
epoll (e.g. man epoll) for a small description about level-triggered vs edge-
triggered events.

> Or is it that when I want to send data I should
>     start the watcher for writes
>     send the data
>     stop the watcher
> ?
this is how I do the writes with libev:
     when I want to send data:
          send directly to the socket
          if the send fails with EWOULDBLOCK
               store the data that could not be send in a buffer
               start the write watcher
           else if the send fails with other error
               close the client
     In the write callback
         stop the write watcher
         resend data you previously stored after EWOULDBLOCK
         if the resend failed with EWOULDBLOCK
              store the data that could not be send in a buffer
              start the write watcher again
         else if the send fails with other error
              close the client

Esentially when I need to send data I simply send it to through the socket and 
only if the send fails with EWOULDBLOCK (that means the write socket buffer is 
full) then I start the write watcher so libev can tell me when there is more 
room in the socket write buffer to send more data. In the write callback then I 
stop the watcher and resume sending the data that could not be send 

> Now who wants to change the Unix Socket stuff out for TCP?
> I may eventually get around to it, but that's not what I need right now,
> interestingly enough.
> I'll try my hand at a client now.
> AJ ONeal
> On Mon, Nov 1, 2010 at 10:03 AM, AJ ONeal <coolaj86 at gmail.com> wrote:
> > Thank you for the link, but this is beyond my current scope of
> > understanding.
> > I was hoping for a simple example.
> > 
> > I'm trying to start out small and learn my way up.
> > 
> > Things like this and the dns example are a bit too heavy for me to able
> > to bite off in a chunk, digest, and take the next bite.
> > 
> > If I also had a call graph, that would help a lot with an example like
> > this, but on it's own there are just too many layers to jump back and
> > forth between to understand what's going on.
> > 
> > Do you happen to have a doxygen/dot (or other) call graph for this code?
> > 
> > AJ ONeal
> > 
> > On Mon, Nov 1, 2010 at 9:03 AM, common at gmx.ch <common at gmx.ch> wrote:
> >> AJ ONeal wrote:
> >>> Thanks.
> >>> 
> >>> I'll keep playing with mine to see if I can get it right, but please
> >>> show me yours as soon as you have it up.
> >> 
> >> It's part of a larger project, it does
> >> 
> >>  * tcp
> >>  * udp
> >>  * tls (via nonblocking openssl)
> >>  * IPV4 & IPv6
> >>  * unix domain sockets
> >>  * client & server
> >>  * rate limiting (in & out) per connection
> >>  * resolve domains inline & nonblocking, so you can just
> >> 
> >> connection_connect("example.com",80);
> >> 
> >> and provides timeouts for almost everything you want to be able to
> >> control, listen, idle, sustain, accept, handshake for ssl
> >> 
> >> http://src.carnivore.it/dionaea/tree/src/connection.c
> >> 
> >> 
> >> Markus

Horacio Sanson

More information about the libev mailing list