[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Simple client. How to handle login prompts.



Hi!

I'm trying to connect a bot to a server called FIBS. First Internet Backgammon Server. (www.fibs.com) The server is really simple with a plain connection. Try it yourself: telnet fibs.com 4321

After some browsing (and failures), I found out that I need an event handling mechanism and buffered input and output. After some more googling, I found that libevent provides all these features.

However, I'm struggling. I can't find examples nor tutorials to help me. And my experience with events and socket programming is limited.

Here is my current skeleton code:
/*Â
Â* A simple event driven code for connecting to FIBS. (First Internet Backgammon Server.)
Â* More info of fibs: www.fibs.com
Â*/
#include <event2/dns.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/util.h>
#include <event2/event.h>

#include <stdio.h>
#include <stdlib.h>

void handler (struct evbuffer *buffer, const struct evbuffer_cb_info *info, void *arg)
{
#if 1
  char buf[1024];
  int n;
  while ((n = evbuffer_remove(buffer, buf, sizeof(buf))) > 0) {
/* handle the message form the server */
    printf( buf );
  }
#else
  size_t len;
  printf(" * ");
  char *request_line;
  request_line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
  if (!request_line) {
  //  Âprintf("No line.\n");
    /* The first line has not arrived yet. */
  } else {
    printf("%s\n", request_line);
    free(request_line);
  }
#endifÂ
}

void readcb(struct bufferevent *bev, void *ptr)
{
  printf("Read callback.\n");
}

void writecb(struct bufferevent *bev, void *ptr)
{
  printf("Write callback.\n");
}

/* Code taken from http example */
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
  if (events & BEV_EVENT_CONNECTED) {
    Âprintf("Connect okay.\n");
  } else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
    Âstruct event_base *base = ptr;
    Âif (events & BEV_EVENT_ERROR) {
        Âint err = bufferevent_socket_get_dns_error(bev);
        Âif (err)
            Âprintf("DNS error: %s\n", evutil_gai_strerror(err));
    Â}
    Âprintf("Closing\n");
    Âbufferevent_free(bev);
    Âevent_base_loopexit(base, NULL);
  }
}

#define FIBS_HOST "fibs.com"
#define FIBS_PORT 4321

int main(int argc, char **argv)
{
  struct event_base *base;
  struct evdns_base *dns_base;
  struct bufferevent *bev;

  base = event_base_new();
  dns_base = evdns_base_new(base, 1);

  bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
  bufferevent_setcb(bev, readcb, writecb, eventcb, base);
  bufferevent_enable(bev, EV_READ|EV_WRITE);
  bufferevent_socket_connect_hostname( bev, dns_base, AF_UNSPEC, FIBS_HOST, FIBS_PORT);

  /* Add callback to the evbuffer. (input buffer) */
  struct evbuffer *input = bufferevent_get_input(bev);
  evbuffer_add_cb( input, handler, NULL );

  event_base_dispatch(base);
  return 0;
}

Here comes all my questions:
* Am I on the right track?
* The login prompt from the server does not send a newline, so the handle is not called. How can I find the login prompt?
* I also try to read the lines in the handle callback evbuffer_readln(), but the lines will then bre printed in the wrong order. Why?

Thanks for any input?
-Ãystein