여러가지 방식의 네트워크 처리 모델을 사용해 봤습니다. 구현 하는 네트워크 엔진에 따라 틀리겠지만, IOCP모델은 지금의 방식이 최선이라 생각됩니다. 대부분 이러한 방식의 구현 방식을 사용하시리라 생각됩니다.
실제 구현할때도 상당히 깔끔해 지는 장점이 있네요... 여러분 들의 개발 모델은 어떠세요?
참고로, 이 모델을 통해 간단히 구현한 acceptor 모델 예제를 첨부합니다.
class Acceptor: public wsaio::acceptor {
public:
Acceptor( int port, int backlog)
{
if (wsaio::listen( this, port, &backlog) < 0)
THROW_EXCEPTION( "Acceptor");
else {
;
} printf( "listen: %d - %d wait\n", port, backlog);
}
static int CACHEIN_FILTER(CRLF)( SOCKET fd, struct ::cache *ca, ULONG_PTR *value)
{
int size;
int offset = 0;
char *buffer;
while ((buffer = cache_pbuffer( ca, &size, offset)) != NULL)
{
int at;
for (at = 0; at < size; at++)
if (*(buffer + at) == '\n')
{
return (offset + at) + 1;
}
offset += size;
} return 0;
}
#define MAX_CACHESIZE 128
class Handler: public wsaio::handler {
public:
Handler( LPWSASOCKET fd, LPSOCKADDR addr)
: m_fd( fd)
{
wsaio::setcache( fd, MAX_CACHESIZE, CACHEIN_FILTER(CRLF), 0, MAX_CACHESIZE);
}
BOOL do_readable( LPWSASOCKET fd, const WSABUF *complet, WSABUF *buff)
{
printf( " do_readable: %d bytes - ", complet->len);
fwrite( complet->buf, 1, complet->len, stdout);
return TRUE;
}
BOOL do_exception( LPWSASOCKET fd, int what, LPVOID info)
{
WSABUF *buf = (WSABUF *)info;
printf( "do_exception: %p fd - %d action - %d\n", fd, what, buf->len);
return TRUE;
}
private:
LPWSASOCKET m_fd;
};
BOOL do_accept( LPWSASOCKET vw, LPSOCKADDR addr)
{
printf( "do_accept: %s\n", inet_ntoa( ((LPSOCKADDR_IN)addr)->sin_addr));
if (wsaio::accept( vw, new Handler( vw, addr)) == NULL)
THROW_EXCEPTION( "wsaio::accept()");
return TRUE;
}
};