mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 09:20:52 +08:00
188 lines
4.5 KiB
C++
188 lines
4.5 KiB
C++
#include "StdAfx.h"
|
|
#include "lib_acl.h"
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "aio_server.h"
|
|
|
|
#define USE_GETS
|
|
|
|
/* forward functions */
|
|
|
|
static char __data[1024];
|
|
static int __dlen;
|
|
static int __echo_src;
|
|
|
|
static int __gets_callback(ACL_ASTREAM *stream, void *context,
|
|
const char *data, int dlen);
|
|
|
|
static void default_write_fn(void *arg acl_unused, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
acl_msg_info2(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
static void default_fflush_fn(void *arg)
|
|
{
|
|
arg = arg;
|
|
}
|
|
|
|
static void (*__write_fn)(void *arg, const char *fmt, ...) = default_write_fn;
|
|
static void *__write_arg = NULL;
|
|
static void (*__fflush_fn)(void *arg) = default_fflush_fn;
|
|
static void *__fflush_arg = NULL;
|
|
|
|
void aio_server_log_fn(void (*write_fn)(void *, const char *fmt, ...),
|
|
void *write_arg,
|
|
void (*fflush_fn)(void *),
|
|
void *fflush_arg)
|
|
{
|
|
if (write_fn) {
|
|
__write_fn = write_fn;
|
|
__write_arg = write_arg;
|
|
}
|
|
|
|
if (fflush_fn) {
|
|
__fflush_fn = fflush_fn;
|
|
__fflush_arg = fflush_arg;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int __io_close(ACL_ASTREAM *astream, void *context acl_unused)
|
|
{
|
|
const char *myname = "__io_close";
|
|
ACL_VSTREAM *stream = acl_aio_vstream(astream);
|
|
|
|
__write_fn(__write_arg, "%s, %s(%d): client(%d) exception!",
|
|
__FILE__, myname, __LINE__, ACL_VSTREAM_SOCK(stream));
|
|
|
|
return (-1);
|
|
}
|
|
|
|
static int __io_timeout(ACL_ASTREAM *astream, void *context acl_unused)
|
|
{
|
|
const char *myname = "__io_timeout";
|
|
ACL_VSTREAM *stream = acl_aio_vstream(astream);
|
|
|
|
__write_fn(__write_arg, "%s, %s(%d): client(%d) timeout!",
|
|
__FILE__, myname, __LINE__, ACL_VSTREAM_SOCK(stream));
|
|
|
|
return (-1);
|
|
}
|
|
static int __write_callback(ACL_ASTREAM *client, void *context acl_unused,
|
|
const char *data acl_unused, int dlen acl_unused)
|
|
{
|
|
#ifdef USE_GETS
|
|
acl_aio_gets(client);
|
|
#else
|
|
acl_aio_read(client);
|
|
#endif
|
|
return (0);
|
|
}
|
|
|
|
static int __gets_callback(ACL_ASTREAM *stream, void *context acl_unused,
|
|
const char *data, int dlen)
|
|
{
|
|
if (__echo_src)
|
|
(void) acl_aio_writen(stream, data, dlen);
|
|
else
|
|
acl_aio_writen(stream, __data, __dlen);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int __accept_callback(ACL_ASTREAM *client, void *context acl_unused)
|
|
{
|
|
acl_aio_ctl(client, ACL_AIO_CTL_READ_HOOK_ADD, __gets_callback, NULL,
|
|
ACL_AIO_CTL_WRITE_HOOK_ADD, __write_callback, NULL,
|
|
ACL_AIO_CTL_CLOSE_HOOK_ADD, __io_close, NULL,
|
|
ACL_AIO_CTL_TIMEO_HOOK_ADD, __io_timeout, NULL,
|
|
ACL_AIO_CTL_END);
|
|
#ifdef USE_GETS
|
|
acl_aio_gets(client);
|
|
#else
|
|
acl_aio_read(client);
|
|
#endif
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void __listen_callback(ACL_ASTREAM *sstream, void *context)
|
|
{
|
|
ACL_VSTREAM *cstream;
|
|
ACL_ASTREAM *client;
|
|
ACL_AIO *aio = (ACL_AIO *) context;
|
|
int i;
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
cstream = acl_vstream_accept(acl_aio_vstream(sstream), NULL, 0);
|
|
if (cstream == NULL)
|
|
break;
|
|
cstream->rw_timeout = 0;
|
|
acl_non_blocking(ACL_VSTREAM_SOCK(cstream), ACL_NON_BLOCKING);
|
|
client = acl_aio_open(aio, cstream);
|
|
acl_aio_ctl(client,
|
|
ACL_AIO_CTL_READ_HOOK_ADD, __gets_callback, NULL,
|
|
ACL_AIO_CTL_WRITE_HOOK_ADD, __write_callback, NULL,
|
|
ACL_AIO_CTL_CLOSE_HOOK_ADD, __io_close, NULL,
|
|
ACL_AIO_CTL_TIMEO_HOOK_ADD, __io_timeout, NULL,
|
|
ACL_AIO_CTL_END);
|
|
#ifdef USE_GETS
|
|
acl_aio_gets(client);
|
|
#else
|
|
acl_aio_read(client);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static ACL_ASTREAM *__listener = NULL;
|
|
|
|
void aiho_server_start(ACL_AIO *aio, const char *addr, int accept_auto, int echo_src)
|
|
{
|
|
const char *myname = "echo_start";
|
|
ACL_VSTREAM *sstream;
|
|
ACL_ASTREAM *astream;
|
|
|
|
memset(__data, 'X', sizeof(__data));
|
|
__data[sizeof(__data) - 1] = 0;
|
|
__data[sizeof(__data) - 2] = '\n';
|
|
__data[sizeof(__data) - 3] = '\r';
|
|
__dlen = (int) strlen(__data);
|
|
__echo_src = echo_src;
|
|
sstream = acl_vstream_listen(addr, 128);
|
|
assert(sstream);
|
|
|
|
acl_aio_set_keep_read(aio, 1);
|
|
|
|
astream = acl_aio_open(aio, sstream);
|
|
__listener = astream;
|
|
|
|
printf(">>>listen: %s ...\r\n", addr);
|
|
|
|
if (!accept_auto) {
|
|
acl_aio_ctl(astream, ACL_AIO_CTL_LISTEN_FN, __listen_callback,
|
|
ACL_AIO_CTL_CTX, aio,
|
|
ACL_AIO_CTL_END);
|
|
acl_aio_listen(astream);
|
|
} else {
|
|
acl_aio_ctl(astream, ACL_AIO_CTL_ACCEPT_FN, __accept_callback,
|
|
ACL_AIO_CTL_CTX, aio,
|
|
ACL_AIO_CTL_END);
|
|
acl_aio_accept(astream);
|
|
}
|
|
}
|
|
|
|
void aio_server_end(void)
|
|
{
|
|
if (__listener) {
|
|
acl_aio_iocp_close(__listener);
|
|
acl_aio_loop(__listener->aio);
|
|
__listener = NULL;
|
|
}
|
|
} |