rendered paste body#ifndef __LISTER_SOCKET_NWIN32_H__
#define __LISTER_SOCKET_NWIN32_H__
#include "Common.h"
#include "Log.h"
#include "SocketManager.h"
template<class T>
class ListenSocket:
public SocketBase
{
public:
ListenSocket(const char* szListenAddress, int unPort):
m_bSocketCreated(false)
{
do
{
if((m_SocketHandle = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
{
sLog.outError("<Listen socket> Couldn't create socket");
break;
}
int on = 1;
if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)) == SOCKET_ERROR)
{
sLog.outError("<Listen socket %u> Couldn't set option SO_REUSEADDR",
m_SocketHandle);
break;
}
u_long arg = 1;
if(ioctlsocket(m_SocketHandle, FIONBIO, &arg) == SOCKET_ERROR)
{
sLog.outError("<Listen socket %u> Couldn't set nonblocking mode",
m_SocketHandle);
break;
}
sockaddr_in address;
if(!strcmp(szListenAddress, "0.0.0.0"))
address.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
hostent* h = gethostbyname(szListenAddress);
if(!h)
{
sLog.outError("<Listen socket %u> Couldn't retrieve host information corresponding "
"to a host name from a host database",
m_SocketHandle);
break;
}
memcpy(&address.sin_addr, h->h_addr_list[0], sizeof(in_addr));
}
address.sin_family = AF_INET;
address.sin_port = ntohs(unPort);
if (bind(m_SocketHandle, (const sockaddr*)&address, sizeof(sockaddr_in)) == SOCKET_ERROR)
{
sLog.outError("<Listen socket %u> Couldn't associate a local address with a socket",
m_SocketHandle);
break;
}
if (listen(m_SocketHandle, 1024) == SOCKET_ERROR)
{
sLog.outError("<Listen socket %u> Couldn't place a socket in a state in which it"
" is listening for an incoming connection",
m_SocketHandle);
break;
}
m_bSocketCreated = true;
}
while(false);
if (m_bSocketCreated && sSocketManager.AddSocket(this))
sLog.outString("<Listen socket %u> Listening started...", m_SocketHandle);
else
{
sLog.outError("<Listen socket %u> Creating failed", m_SocketHandle);
StopListening();
}
}
void Disconnect(bool bAbort = false) { StopListening(); }
bool IsConnected() { return IsListenPortOpened(); }
bool IsListenPortOpened() { return m_bSocketCreated;}
void ScheduleReading()
{
#ifdef WIN32
timeval tv = {0, 50000};
#else
timeval tv = {5, 0};
#endif
if(event_add(&m_ev_read, &tv) == -1)
sLog.outError("<Listen socket %u> Couldn't reschedule reading by timeout. Error [%u].",
GetSocket(), errno);
}
void OnWriteEvent() {}
void OnTimeoutEvent()
{
ScheduleReading();
}
void OnAddSocket()
{
event_set(&m_ev_read, (int)GetSocket(), EV_READ | EV_PERSIST, io_handle, (SocketBase*)this);
event_base_set(sSocketManager.GetEventBase(), &m_ev_read);
#ifdef WIN32
timeval tv = {0, 50000};
#else
timeval tv = {5, 0};
#endif
if(event_add(&m_ev_read, &tv) == -1)
sLog.outError("<Listen socket %u> Couldn't add EV_READ | EV_PERSIST event on creating",
GetSocket());
}
void OnRemoveSocket()
{
if(event_del(&m_ev_read) == -1)
sLog.outError("<Listen socket %u> Couldn't delete READ event on exit", GetSocket());
}
void OnReadEvent()
{
ScheduleReading();
struct sockaddr_in ClientAddress;
socklen_t addrlen = sizeof(ClientAddress);
SOCKET client_sock = INVALID_SOCKET;
if ((client_sock = accept(m_SocketHandle, (sockaddr*)&ClientAddress, &addrlen)) == INVALID_SOCKET)
{
sLog.outError("<Listen socket %u> Couldn't accept connection. Some error. Skipped.",
m_SocketHandle);
return;
}
sLog.outString("<Listen socket %u> Accepted new connection. Socket %u",
m_SocketHandle, client_sock);
T* pSocket = new T(client_sock);
pSocket->Accept(&ClientAddress);
}
void StopListening()
{
sLog.outBasic("<Listen socket %u> Listen socket closed", m_SocketHandle);
sSocketManager.RemoveSocket(this);
::closesocket(m_SocketHandle);
m_bSocketCreated = false;
}
private:
bool m_bSocketCreated;
};
#endif//__LISTER_SOCKET_NWIN32_H__