[fpc-pascal] libevent for socket

silvioprog silvioprog at gmail.com
Sun Jan 17 20:34:45 CET 2016


On Tue, Jan 5, 2016 at 12:15 PM, Xiangrong Fang <xrfang at gmail.com> wrote:

> Hi All,
>
> Could anyone help me with some samples of writing socket program with
> libevent, or is there any adapter/wrapper already exists for freepascal?
>

I used libevent in a C project, but you can use it easily with Pascal (FPC
and/or Delphi). For example, I did this small draft [1] that compiles in
Free Pascal (it is just a helloworld fast HTTP server), using the libevent
2.0.5:

=== begin code ===

program helloworld;

{$mode objfpc}{$H+}

uses
{$IFDEF MSWINDOWS}
  WinSock2,
{$ENDIF}
  ctypes;

const
  EV_LIB_NAME = {$IFDEF MSWINDOWS}'libevent-2-0-5'{$ELSE}'event'{$ENDIF};

{$IFDEF FPC}
  {$PACKRECORDS C}
{$ENDIF}

const
  HTTP_OK = 200;

type
  pcchar = PAnsiChar;

  evbuffer = packed record
  end;
  Pevbuffer = ^evbuffer;

  event_base = packed record
  end;
  Pevent_base = ^event_base;

  evhttp = packed record
  end;
  Pevhttp = ^evhttp;

  evhttp_request = packed record
  end;
  Pevhttp_request = ^evhttp_request;

  evkeyvalq = packed record
  end;
  Pevkeyvalq = ^evkeyvalq;

  evhttp_set_gencb_cb = procedure(p1: Pevhttp_request; p2: Pointer); cdecl;

  function evbuffer_add_printf(buf: Pevbuffer; fmt: pcchar): cint; cdecl;
varargs; external EV_LIB_NAME name 'evbuffer_add_printf';
  function event_init: pevent_base; cdecl; external EV_LIB_NAME name
'event_init';
  function event_dispatch: cint; cdecl; external EV_LIB_NAME name
'event_dispatch';
  function evhttp_start(address: pcchar;  port: cshort): pevhttp; cdecl;
external EV_LIB_NAME name 'evhttp_start';
  function evbuffer_new: Pevbuffer; cdecl; external EV_LIB_NAME name
'evbuffer_new';
  procedure evhttp_set_gencb(http: Pevhttp; cb: evhttp_set_gencb_cb; arg:
Pointer); cdecl; external EV_LIB_NAME name 'evhttp_set_gencb';
  function evhttp_add_header(headers: Pevkeyvalq; key: pcchar; value:
pcchar): cint; cdecl; external EV_LIB_NAME name 'evhttp_add_header';
  function evhttp_request_get_output_headers(req: Pevhttp_request):
Pevkeyvalq; cdecl; external EV_LIB_NAME name
'evhttp_request_get_output_headers';
  procedure evhttp_send_reply_start(req: Pevhttp_request; code: cint;
reason: pcchar); cdecl; external EV_LIB_NAME name 'evhttp_send_reply_start';
  procedure evhttp_send_reply_chunk(req: Pevhttp_request; databuf:
Pevbuffer); cdecl; external EV_LIB_NAME name 'evhttp_send_reply_chunk';
  procedure evhttp_send_reply_end(req: Pevhttp_request); cdecl; external
EV_LIB_NAME name 'evhttp_send_reply_end';
  procedure evbuffer_free(buf: Pevbuffer); cdecl; external EV_LIB_NAME name
'evbuffer_free';

  procedure generic_request_handler(req: Pevhttp_request; arg: Pointer);
cdecl;
  var
    returnbuffer: Pevbuffer;
  begin
    returnbuffer := evbuffer_new;
    evhttp_add_header(evhttp_request_get_output_headers(req),
'Content-Type', 'text/html');
    evhttp_add_header(evhttp_request_get_output_headers(req), 'Connection',
'keep-alive');
    evbuffer_add_printf(returnbuffer, '<html><head><title>Hello
world</title></head><body>Hello world</body></html>');
    evhttp_send_reply_start(req, HTTP_OK, 'OK');
    // Chuncked reply
    evhttp_send_reply_chunk(req, returnbuffer);
    evhttp_send_reply_end(req);
    evbuffer_free(returnbuffer);
  end;

var
  http_port: cshort = 8080;
  http_addr: pcchar = '0.0.0.0';
  http_server: Pevhttp = nil;
{$IFDEF MSWINDOWS}
  wsa_data: WSAData;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
  WSAStartup($0201, wsa_data);
{$ENDIF}
  event_init;
  http_server := evhttp_start(http_addr, http_port);
  evhttp_set_gencb(http_server, @generic_request_handler, nil); // Callback
on event
  WriteLn('Server started on port ', http_port);
  WriteLn('Press [ENTER] to exit ...');
  event_dispatch;
end.

=== end code ===

-- 
Silvio Clécio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20160117/1d66aecf/attachment.html>


More information about the fpc-pascal mailing list