Started to implement server state engine.
This commit is contained in:
+9
-2
@@ -64,7 +64,7 @@ HEADERS += src/game.h \
|
|||||||
src/engine/turninterface.h \
|
src/engine/turninterface.h \
|
||||||
src/gui/guiinterface.h \
|
src/gui/guiinterface.h \
|
||||||
src/net/clientcallback.h \
|
src/net/clientcallback.h \
|
||||||
src/net/clientdata.h \
|
src/net/clientcontext.h \
|
||||||
src/net/clientexception.h \
|
src/net/clientexception.h \
|
||||||
src/net/clientstate.h \
|
src/net/clientstate.h \
|
||||||
src/net/clientthread.h \
|
src/net/clientthread.h \
|
||||||
@@ -139,17 +139,24 @@ SOURCES += src/game.cpp \
|
|||||||
src/engine/local_engine/localturn.cpp \
|
src/engine/local_engine/localturn.cpp \
|
||||||
src/engine/local_engine/tools.cpp \
|
src/engine/local_engine/tools.cpp \
|
||||||
src/gui/qt/guiwrapper.cpp \
|
src/gui/qt/guiwrapper.cpp \
|
||||||
|
src/net/common/connectdata.cpp \
|
||||||
src/net/common/clientcallback.cpp \
|
src/net/common/clientcallback.cpp \
|
||||||
src/net/common/clientdata.cpp \
|
src/net/common/clientcontext.cpp \
|
||||||
src/net/common/clientstate.cpp \
|
src/net/common/clientstate.cpp \
|
||||||
src/net/common/clientthread.cpp \
|
src/net/common/clientthread.cpp \
|
||||||
src/net/common/netpacket.cpp \
|
src/net/common/netpacket.cpp \
|
||||||
src/net/common/resolverthread.cpp \
|
src/net/common/resolverthread.cpp \
|
||||||
src/net/common/senderthread.cpp \
|
src/net/common/senderthread.cpp \
|
||||||
|
src/net/common/sendercallback.cpp \
|
||||||
src/net/common/serverthread.cpp \
|
src/net/common/serverthread.cpp \
|
||||||
|
src/net/common/servercontext.cpp \
|
||||||
|
src/net/common/serverexception.cpp \
|
||||||
|
src/net/common/serverrecvthread.cpp \
|
||||||
|
src/net/common/serverrecvstate.cpp \
|
||||||
src/net/common/socket_helper_cmn.cpp \
|
src/net/common/socket_helper_cmn.cpp \
|
||||||
src/net/common/clientexception.cpp \
|
src/net/common/clientexception.cpp \
|
||||||
src/net/common/netcallback.cpp \
|
src/net/common/netcallback.cpp \
|
||||||
|
src/net/common/netcontext.cpp \
|
||||||
src/net/common/netexception.cpp \
|
src/net/common/netexception.cpp \
|
||||||
src/net/common/receiverhelper.cpp \
|
src/net/common/receiverhelper.cpp \
|
||||||
src/gui/qt/aboutpokerth/aboutpokerthimpl.cpp \
|
src/gui/qt/aboutpokerth/aboutpokerthimpl.cpp \
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ void connectToServerDialogImpl::error(int errorID, int osErrorID) {
|
|||||||
tr("Could not create a socket for TCP communication."),
|
tr("Could not create a socket for TCP communication."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
break;
|
break;
|
||||||
|
case ERR_SOCK_SET_ADDR_FAILED:
|
||||||
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
|
tr("Could not set the IP address."),
|
||||||
|
QMessageBox::Close); }
|
||||||
|
break;
|
||||||
case ERR_SOCK_SET_PORT_FAILED:
|
case ERR_SOCK_SET_PORT_FAILED:
|
||||||
{ QMessageBox::warning(this, tr("Network Error"),
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
tr("Could not set the port for this type of address."),
|
tr("Could not set the port for this type of address."),
|
||||||
@@ -79,6 +84,21 @@ void connectToServerDialogImpl::error(int errorID, int osErrorID) {
|
|||||||
tr("The server name could not be resolved."),
|
tr("The server name could not be resolved."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
break;
|
break;
|
||||||
|
case ERR_SOCK_BIND_FAILED:
|
||||||
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
|
tr("Bind failed - please choose a different port."),
|
||||||
|
QMessageBox::Close); }
|
||||||
|
break;
|
||||||
|
case ERR_SOCK_LISTEN_FAILED:
|
||||||
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
|
tr("Internal network error: \"listen\" failed."),
|
||||||
|
QMessageBox::Close); }
|
||||||
|
break;
|
||||||
|
case ERR_SOCK_ACCEPT_FAILED:
|
||||||
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
|
tr("Server execution was terminated."),
|
||||||
|
QMessageBox::Close); }
|
||||||
|
break;
|
||||||
case ERR_SOCK_CONNECT_FAILED:
|
case ERR_SOCK_CONNECT_FAILED:
|
||||||
{ QMessageBox::warning(this, tr("Network Error"),
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
tr("Could not connect to the server."),
|
tr("Could not connect to the server."),
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ class ClientCallback : public NetCallback
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ClientCallback();
|
virtual ~ClientCallback();
|
||||||
|
|
||||||
virtual void SignalNetSuccess(int actionID) = 0;
|
|
||||||
virtual void SignalNetError(int errorID, int osErrorID) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Context of network client. */
|
||||||
|
|
||||||
|
#ifndef _CLIENTCONTEXT_H_
|
||||||
|
#define _CLIENTCONTEXT_H_
|
||||||
|
|
||||||
|
#include <net/netcontext.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ClientContext : public NetContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientContext();
|
||||||
|
virtual ~ClientContext();
|
||||||
|
|
||||||
|
virtual SOCKET GetSocket() const;
|
||||||
|
virtual u_int32_t GetId() const;
|
||||||
|
|
||||||
|
void SetSocket(SOCKET sockfd);
|
||||||
|
|
||||||
|
int GetAddrFamily() const
|
||||||
|
{return m_addrFamily;}
|
||||||
|
void SetAddrFamily(int addrFamily)
|
||||||
|
{m_addrFamily = addrFamily;}
|
||||||
|
const std::string &GetServerAddr() const
|
||||||
|
{return m_serverAddr;}
|
||||||
|
void SetServerAddr(const std::string &serverAddr)
|
||||||
|
{m_serverAddr = serverAddr;}
|
||||||
|
unsigned GetServerPort() const
|
||||||
|
{return m_serverPort;}
|
||||||
|
void SetServerPort(unsigned serverPort)
|
||||||
|
{m_serverPort = serverPort;}
|
||||||
|
const std::string &GetPassword() const
|
||||||
|
{return m_password;}
|
||||||
|
void SetPassword(const std::string &password)
|
||||||
|
{m_password = password;}
|
||||||
|
const sockaddr_storage *GetClientSockaddr() const
|
||||||
|
{return &m_clientSockaddr;}
|
||||||
|
sockaddr_storage *GetClientSockaddr()
|
||||||
|
{return &m_clientSockaddr;}
|
||||||
|
|
||||||
|
int GetClientSockaddrSize() const
|
||||||
|
{return m_addrFamily == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SOCKET m_sockfd;
|
||||||
|
int m_addrFamily;
|
||||||
|
std::string m_serverAddr;
|
||||||
|
unsigned m_serverPort;
|
||||||
|
std::string m_password;
|
||||||
|
sockaddr_storage m_clientSockaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+10
-4
@@ -25,11 +25,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class ClientData;
|
class ClientContext;
|
||||||
class ClientState;
|
class ClientState;
|
||||||
class ClientCallback;
|
class ClientCallback;
|
||||||
class SenderThread;
|
class SenderThread;
|
||||||
class ReceiverHelper;
|
class ReceiverHelper;
|
||||||
|
class ClientSenderCallback;
|
||||||
|
|
||||||
class ClientThread : public Thread
|
class ClientThread : public Thread
|
||||||
{
|
{
|
||||||
@@ -42,13 +43,15 @@ public:
|
|||||||
// (i.e. after starting the thread).
|
// (i.e. after starting the thread).
|
||||||
void Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &pwd);
|
void Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &pwd);
|
||||||
|
|
||||||
|
ClientCallback &GetCallback();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Main function of the thread.
|
// Main function of the thread.
|
||||||
virtual void Main();
|
virtual void Main();
|
||||||
|
|
||||||
const ClientData &GetData() const;
|
const ClientContext &GetContext() const;
|
||||||
ClientData &GetData();
|
ClientContext &GetContext();
|
||||||
|
|
||||||
ClientState &GetState();
|
ClientState &GetState();
|
||||||
void SetState(ClientState &newState);
|
void SetState(ClientState &newState);
|
||||||
@@ -56,9 +59,12 @@ protected:
|
|||||||
SenderThread &GetSender();
|
SenderThread &GetSender();
|
||||||
ReceiverHelper &GetReceiver();
|
ReceiverHelper &GetReceiver();
|
||||||
|
|
||||||
|
ClientSenderCallback &GetSenderCallback();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::auto_ptr<ClientData> m_data;
|
std::auto_ptr<ClientContext> m_context;
|
||||||
|
std::auto_ptr<ClientSenderCallback> m_senderCallback;
|
||||||
ClientState *m_curState;
|
ClientState *m_curState;
|
||||||
ClientCallback &m_callback;
|
ClientCallback &m_callback;
|
||||||
std::auto_ptr<SenderThread> m_sender;
|
std::auto_ptr<SenderThread> m_sender;
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/clientcontext.h>
|
||||||
|
|
||||||
|
ClientContext::ClientContext()
|
||||||
|
: m_sockfd(INVALID_SOCKET), m_addrFamily(AF_INET), m_serverPort(0)
|
||||||
|
{
|
||||||
|
bzero(&m_clientSockaddr, sizeof(m_clientSockaddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientContext::~ClientContext()
|
||||||
|
{
|
||||||
|
if (m_sockfd != INVALID_SOCKET)
|
||||||
|
CLOSESOCKET(m_sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET
|
||||||
|
ClientContext::GetSocket() const
|
||||||
|
{
|
||||||
|
return m_sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t
|
||||||
|
ClientContext::GetId() const
|
||||||
|
{
|
||||||
|
// Id is unused for clients.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientContext::SetSocket(SOCKET sockfd)
|
||||||
|
{
|
||||||
|
m_sockfd = sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <net/clientstate.h>
|
#include <net/clientstate.h>
|
||||||
#include <net/clientthread.h>
|
#include <net/clientthread.h>
|
||||||
#include <net/clientdata.h>
|
#include <net/clientcontext.h>
|
||||||
#include <net/senderthread.h>
|
#include <net/senderthread.h>
|
||||||
#include <net/receiverhelper.h>
|
#include <net/receiverhelper.h>
|
||||||
#include <net/netpacket.h>
|
#include <net/netpacket.h>
|
||||||
@@ -28,11 +28,9 @@
|
|||||||
#include <net/socket_helper.h>
|
#include <net/socket_helper.h>
|
||||||
#include <net/socket_msg.h>
|
#include <net/socket_msg.h>
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define CLIENT_WAIT_TIMEOUT_MSEC 100
|
#define CLIENT_WAIT_TIMEOUT_MSEC 50
|
||||||
|
|
||||||
|
|
||||||
ClientState::~ClientState()
|
ClientState::~ClientState()
|
||||||
@@ -59,20 +57,20 @@ ClientStateInit::~ClientStateInit()
|
|||||||
int
|
int
|
||||||
ClientStateInit::Process(ClientThread &client)
|
ClientStateInit::Process(ClientThread &client)
|
||||||
{
|
{
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
|
|
||||||
if (data.serverAddr.empty())
|
if (context.GetServerAddr().empty())
|
||||||
throw ClientException(ERR_SOCK_SERVERADDR_NOT_SET, 0);
|
throw ClientException(ERR_SOCK_SERVERADDR_NOT_SET, 0);
|
||||||
|
|
||||||
// if (data.serverPort < 1024)
|
// if (context.GetServerPort() < 1024)
|
||||||
// throw ClientException(ERR_SOCK_INVALID_PORT, 0);
|
// throw ClientException(ERR_SOCK_INVALID_PORT, 0);
|
||||||
|
|
||||||
data.sockfd = socket(data.addrFamily, SOCK_STREAM, 0);
|
context.SetSocket(socket(context.GetAddrFamily(), SOCK_STREAM, 0));
|
||||||
if (!IS_VALID_SOCKET(data.sockfd))
|
if (!IS_VALID_SOCKET(context.GetSocket()))
|
||||||
throw ClientException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
throw ClientException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
||||||
|
|
||||||
unsigned long mode = 1;
|
unsigned long mode = 1;
|
||||||
if (IOCTLSOCKET(data.sockfd, FIONBIO, &mode) == SOCKET_ERROR)
|
if (IOCTLSOCKET(context.GetSocket(), FIONBIO, &mode) == SOCKET_ERROR)
|
||||||
throw ClientException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
throw ClientException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
||||||
|
|
||||||
client.SetState(ClientStateStartResolve::Instance());
|
client.SetState(ClientStateStartResolve::Instance());
|
||||||
@@ -102,19 +100,19 @@ ClientStateStartResolve::Process(ClientThread &client)
|
|||||||
{
|
{
|
||||||
int retVal;
|
int retVal;
|
||||||
|
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
|
|
||||||
data.clientAddr.ss_family = data.addrFamily;
|
context.GetClientSockaddr()->ss_family = context.GetAddrFamily();
|
||||||
|
|
||||||
// Treat the server address as numbers first.
|
// Treat the server address as numbers first.
|
||||||
if (socket_string_to_addr(
|
if (socket_string_to_addr(
|
||||||
data.serverAddr.c_str(),
|
context.GetServerAddr().c_str(),
|
||||||
data.addrFamily,
|
context.GetAddrFamily(),
|
||||||
(struct sockaddr *)&data.clientAddr,
|
(struct sockaddr *)context.GetClientSockaddr(),
|
||||||
data.GetServerAddrSize()))
|
context.GetClientSockaddrSize()))
|
||||||
{
|
{
|
||||||
// Success - but we still need to set the port.
|
// Success - but we still need to set the port.
|
||||||
if (!socket_set_port(data.serverPort, data.addrFamily, (struct sockaddr *)&data.clientAddr, data.GetServerAddrSize()))
|
if (!socket_set_port(context.GetServerPort(), context.GetAddrFamily(), (struct sockaddr *)context.GetClientSockaddr(), context.GetClientSockaddrSize()))
|
||||||
throw ClientException(ERR_SOCK_SET_PORT_FAILED, 0);
|
throw ClientException(ERR_SOCK_SET_PORT_FAILED, 0);
|
||||||
|
|
||||||
// No need to resolve - start connecting.
|
// No need to resolve - start connecting.
|
||||||
@@ -126,7 +124,7 @@ ClientStateStartResolve::Process(ClientThread &client)
|
|||||||
// Start name resolution in a separate thread, since it is blocking
|
// Start name resolution in a separate thread, since it is blocking
|
||||||
// for up to about 30 seconds.
|
// for up to about 30 seconds.
|
||||||
std::auto_ptr<ResolverThread> resolver(new ResolverThread);
|
std::auto_ptr<ResolverThread> resolver(new ResolverThread);
|
||||||
resolver->Init(data);
|
resolver->Init(context);
|
||||||
resolver->Run();
|
resolver->Run();
|
||||||
|
|
||||||
ClientStateResolving::Instance().SetResolver(resolver.release());
|
ClientStateResolving::Instance().SetResolver(resolver.release());
|
||||||
@@ -175,8 +173,8 @@ ClientStateResolving::Process(ClientThread &client)
|
|||||||
|
|
||||||
if (m_resolver->Join(CLIENT_WAIT_TIMEOUT_MSEC))
|
if (m_resolver->Join(CLIENT_WAIT_TIMEOUT_MSEC))
|
||||||
{
|
{
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
bool success = m_resolver->GetResult(data);
|
bool success = m_resolver->GetResult(context);
|
||||||
Cleanup(); // Not required, but better keep things clean.
|
Cleanup(); // Not required, but better keep things clean.
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
@@ -226,9 +224,9 @@ int
|
|||||||
ClientStateStartConnect::Process(ClientThread &client)
|
ClientStateStartConnect::Process(ClientThread &client)
|
||||||
{
|
{
|
||||||
int retVal;
|
int retVal;
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
|
|
||||||
int connectResult = connect(data.sockfd, (struct sockaddr *)&data.clientAddr, data.GetServerAddrSize());
|
int connectResult = connect(context.GetSocket(), (struct sockaddr *)context.GetClientSockaddr(), context.GetClientSockaddrSize());
|
||||||
|
|
||||||
if (IS_VALID_CONNECT(connectResult))
|
if (IS_VALID_CONNECT(connectResult))
|
||||||
{
|
{
|
||||||
@@ -271,24 +269,24 @@ int
|
|||||||
ClientStateConnecting::Process(ClientThread &client)
|
ClientStateConnecting::Process(ClientThread &client)
|
||||||
{
|
{
|
||||||
int retVal;
|
int retVal;
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
|
|
||||||
fd_set writeSet;
|
fd_set writeSet;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
FD_ZERO(&writeSet);
|
FD_ZERO(&writeSet);
|
||||||
FD_SET(data.sockfd, &writeSet);
|
FD_SET(context.GetSocket(), &writeSet);
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = CLIENT_WAIT_TIMEOUT_MSEC * 1000;
|
timeout.tv_usec = CLIENT_WAIT_TIMEOUT_MSEC * 1000;
|
||||||
int selectResult = select(data.sockfd + 1, NULL, &writeSet, NULL, &timeout);
|
int selectResult = select(context.GetSocket() + 1, NULL, &writeSet, NULL, &timeout);
|
||||||
|
|
||||||
if (selectResult > 0) // success
|
if (selectResult > 0) // success
|
||||||
{
|
{
|
||||||
// Check whether the connect call succeeded.
|
// Check whether the connect call succeeded.
|
||||||
int connectResult = 0;
|
int connectResult = 0;
|
||||||
socklen_t tmpSize = sizeof(connectResult);
|
socklen_t tmpSize = sizeof(connectResult);
|
||||||
getsockopt(data.sockfd, SOL_SOCKET, SO_ERROR, (char *)&connectResult, &tmpSize);
|
getsockopt(context.GetSocket(), SOL_SOCKET, SO_ERROR, (char *)&connectResult, &tmpSize);
|
||||||
if (connectResult != 0)
|
if (connectResult != 0)
|
||||||
throw ClientException(ERR_SOCK_CONNECT_FAILED, connectResult);
|
throw ClientException(ERR_SOCK_CONNECT_FAILED, connectResult);
|
||||||
client.SetState(ClientStateStartSession::Instance());
|
client.SetState(ClientStateStartSession::Instance());
|
||||||
@@ -323,12 +321,8 @@ ClientStateStartSession::~ClientStateStartSession()
|
|||||||
int
|
int
|
||||||
ClientStateStartSession::Process(ClientThread &client)
|
ClientStateStartSession::Process(ClientThread &client)
|
||||||
{
|
{
|
||||||
client.GetReceiver().Init(client.GetData().sockfd);
|
|
||||||
client.GetSender().Init(client.GetData().sockfd);
|
|
||||||
client.GetSender().Run();
|
|
||||||
|
|
||||||
boost::shared_ptr<NetPacket> packet(new TestNetPacket(10));
|
boost::shared_ptr<NetPacket> packet(new TestNetPacket(10));
|
||||||
client.GetSender().Send(packet);
|
client.GetSender().Send(packet, client.GetContext().GetSocket());
|
||||||
|
|
||||||
client.SetState(ClientStateWaitSession::Instance());
|
client.SetState(ClientStateWaitSession::Instance());
|
||||||
|
|
||||||
@@ -356,11 +350,11 @@ int
|
|||||||
ClientStateWaitSession::Process(ClientThread &client)
|
ClientStateWaitSession::Process(ClientThread &client)
|
||||||
{
|
{
|
||||||
int retVal;
|
int retVal;
|
||||||
ClientData &data = client.GetData();
|
ClientContext &context = client.GetContext();
|
||||||
|
|
||||||
// delegate to receiver helper class
|
// delegate to receiver helper class
|
||||||
|
|
||||||
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv();
|
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(context.GetSocket());
|
||||||
|
|
||||||
if (tmpPacket.get())
|
if (tmpPacket.get())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <net/clientthread.h>
|
#include <net/clientthread.h>
|
||||||
#include <net/clientstate.h>
|
#include <net/clientstate.h>
|
||||||
#include <net/clientdata.h>
|
#include <net/clientcontext.h>
|
||||||
#include <net/senderthread.h>
|
#include <net/senderthread.h>
|
||||||
#include <net/receiverhelper.h>
|
#include <net/receiverhelper.h>
|
||||||
#include <net/clientcallback.h>
|
#include <net/clientcallback.h>
|
||||||
@@ -32,10 +32,30 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class ClientSenderCallback : public SenderCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientSenderCallback(ClientThread &client) : m_client(client) {}
|
||||||
|
virtual ~ClientSenderCallback() {}
|
||||||
|
|
||||||
|
virtual void SignalNetError(SOCKET sock, int errorID, int osErrorID)
|
||||||
|
{
|
||||||
|
// For now, we ignore the socket.
|
||||||
|
// Just signal the error.
|
||||||
|
// We assume that the client thread will be terminated.
|
||||||
|
m_client.GetCallback().SignalNetError(errorID, osErrorID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ClientThread &m_client;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ClientThread::ClientThread(ClientCallback &cb)
|
ClientThread::ClientThread(ClientCallback &cb)
|
||||||
: m_curState(NULL), m_callback(cb)
|
: m_curState(NULL), m_callback(cb)
|
||||||
{
|
{
|
||||||
m_data.reset(new ClientData);
|
m_context.reset(new ClientContext);
|
||||||
|
m_senderCallback.reset(new ClientSenderCallback(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientThread::~ClientThread()
|
ClientThread::~ClientThread()
|
||||||
@@ -48,47 +68,57 @@ ClientThread::Init(const string &serverAddress, unsigned serverPort, bool ipv6,
|
|||||||
if (IsRunning())
|
if (IsRunning())
|
||||||
return; // TODO: throw exception
|
return; // TODO: throw exception
|
||||||
|
|
||||||
ClientData &data = GetData();
|
ClientContext &context = GetContext();
|
||||||
|
|
||||||
data.addrFamily = ipv6 ? AF_INET6 : AF_INET;
|
context.SetAddrFamily(ipv6 ? AF_INET6 : AF_INET);
|
||||||
data.serverAddr = serverAddress;
|
context.SetServerAddr(serverAddress);
|
||||||
data.serverPort = serverPort;
|
context.SetServerPort(serverPort);
|
||||||
data.password = pwd;
|
context.SetPassword(pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientCallback &
|
||||||
|
ClientThread::GetCallback()
|
||||||
|
{
|
||||||
|
return m_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientThread::Main()
|
ClientThread::Main()
|
||||||
{
|
{
|
||||||
m_sender.reset(new SenderThread(m_callback));
|
|
||||||
m_receiver.reset(new ReceiverHelper);
|
|
||||||
SetState(CLIENT_INITIAL_STATE::Instance());
|
SetState(CLIENT_INITIAL_STATE::Instance());
|
||||||
try {
|
|
||||||
|
m_sender.reset(new SenderThread(GetSenderCallback()));
|
||||||
|
m_receiver.reset(new ReceiverHelper);
|
||||||
|
GetSender().Run();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
while (!ShouldTerminate())
|
while (!ShouldTerminate())
|
||||||
{
|
{
|
||||||
int msg = GetState().Process(*this);
|
int msg = GetState().Process(*this);
|
||||||
if (msg != MSG_SOCK_INTERNAL_PENDING)
|
if (msg != MSG_SOCK_INTERNAL_PENDING)
|
||||||
m_callback.SignalNetSuccess(msg);
|
GetCallback().SignalNetSuccess(msg);
|
||||||
}
|
}
|
||||||
} catch (const NetException &e)
|
} catch (const NetException &e)
|
||||||
{
|
{
|
||||||
m_callback.SignalNetError(e.GetErrorId(), e.GetOsErrorCode());
|
GetCallback().SignalNetError(e.GetErrorId(), e.GetOsErrorCode());
|
||||||
}
|
}
|
||||||
GetSender().SignalTermination();
|
GetSender().SignalTermination();
|
||||||
GetSender().Join(100);
|
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClientData &
|
const ClientContext &
|
||||||
ClientThread::GetData() const
|
ClientThread::GetContext() const
|
||||||
{
|
{
|
||||||
assert(m_data.get());
|
assert(m_context.get());
|
||||||
return *m_data;
|
return *m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientData &
|
ClientContext &
|
||||||
ClientThread::GetData()
|
ClientThread::GetContext()
|
||||||
{
|
{
|
||||||
assert(m_data.get());
|
assert(m_context.get());
|
||||||
return *m_data;
|
return *m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientState &
|
ClientState &
|
||||||
@@ -118,3 +148,10 @@ ClientThread::GetReceiver()
|
|||||||
return *m_receiver;
|
return *m_receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientSenderCallback &
|
||||||
|
ClientThread::GetSenderCallback()
|
||||||
|
{
|
||||||
|
assert(m_senderCallback.get());
|
||||||
|
return *m_senderCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,17 +17,17 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <net/clientdata.h>
|
#include <net/connectdata.h>
|
||||||
|
|
||||||
ClientData::ClientData()
|
ConnectData::ConnectData()
|
||||||
: sockfd(INVALID_SOCKET), addrFamily(AF_INET), serverPort(0)
|
: m_sockfd(INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
bzero(&clientAddr, sizeof(clientAddr));
|
bzero(&m_sockaddr, sizeof(m_sockaddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientData::~ClientData()
|
ConnectData::~ConnectData()
|
||||||
{
|
{
|
||||||
if (sockfd != INVALID_SOCKET)
|
if (m_sockfd != INVALID_SOCKET)
|
||||||
CLOSESOCKET(sockfd);
|
CLOSESOCKET(m_sockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/netcontext.h>
|
||||||
|
|
||||||
|
NetContext::~NetContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ ReceiverHelper::Init(SOCKET socket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<NetPacket>
|
boost::shared_ptr<NetPacket>
|
||||||
ReceiverHelper::Recv()
|
ReceiverHelper::Recv(SOCKET sock)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<NetPacket> tmpPacket(InternalGetPacket());
|
boost::shared_ptr<NetPacket> tmpPacket(InternalGetPacket());
|
||||||
|
|
||||||
@@ -59,18 +59,18 @@ ReceiverHelper::Recv()
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
FD_ZERO(&readSet);
|
||||||
FD_SET(m_socket, &readSet);
|
FD_SET(sock, &readSet);
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
|
timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
|
||||||
int selectResult = select(m_socket + 1, &readSet, NULL, NULL, &timeout);
|
int selectResult = select(sock + 1, &readSet, NULL, NULL, &timeout);
|
||||||
if (!IS_VALID_SELECT(selectResult))
|
if (!IS_VALID_SELECT(selectResult))
|
||||||
{
|
{
|
||||||
throw NetException(ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
|
throw NetException(ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
|
||||||
}
|
}
|
||||||
if (selectResult > 0) // recv is possible
|
if (selectResult > 0) // recv is possible
|
||||||
{
|
{
|
||||||
int bytesRecvd = recv(m_socket, m_tmpInBuf + m_tmpInBufSize, bufSize, 0);
|
int bytesRecvd = recv(sock, m_tmpInBuf + m_tmpInBufSize, bufSize, 0);
|
||||||
|
|
||||||
if (!IS_VALID_RECV(bytesRecvd))
|
if (!IS_VALID_RECV(bytesRecvd))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <net/resolverthread.h>
|
#include <net/resolverthread.h>
|
||||||
#include <net/clientdata.h>
|
#include <net/clientcontext.h>
|
||||||
#include <net/clientexception.h>
|
#include <net/clientexception.h>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -30,7 +30,7 @@ using namespace std;
|
|||||||
ResolverThread::ResolverThread()
|
ResolverThread::ResolverThread()
|
||||||
: m_retVal(false)
|
: m_retVal(false)
|
||||||
{
|
{
|
||||||
m_data.reset(new ClientData);
|
m_context.reset(new ClientContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolverThread::~ResolverThread()
|
ResolverThread::~ResolverThread()
|
||||||
@@ -38,24 +38,24 @@ ResolverThread::~ResolverThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ResolverThread::Init(const ClientData &data)
|
ResolverThread::Init(const ClientContext &context)
|
||||||
{
|
{
|
||||||
if (IsRunning())
|
if (IsRunning())
|
||||||
return; // TODO: throw exception
|
return; // TODO: throw exception
|
||||||
|
|
||||||
m_data->addrFamily = data.addrFamily;
|
GetContext().SetAddrFamily(context.GetAddrFamily());
|
||||||
m_data->serverAddr = data.serverAddr;
|
GetContext().SetServerAddr(context.GetServerAddr());
|
||||||
m_data->serverPort = data.serverPort;
|
GetContext().SetServerPort(context.GetServerPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ResolverThread::GetResult(ClientData &data)
|
ResolverThread::GetResult(ClientContext &context) const
|
||||||
{
|
{
|
||||||
if (IsRunning())
|
if (IsRunning())
|
||||||
return false; // TODO: throw exception
|
return false; // TODO: throw exception
|
||||||
|
|
||||||
if (m_retVal)
|
if (m_retVal)
|
||||||
memcpy(&data.clientAddr, &GetData().clientAddr, GetData().GetServerAddrSize());
|
memcpy(context.GetClientSockaddr(), GetContext().GetClientSockaddr(), GetContext().GetClientSockaddrSize());
|
||||||
|
|
||||||
return m_retVal;
|
return m_retVal;
|
||||||
}
|
}
|
||||||
@@ -63,34 +63,34 @@ ResolverThread::GetResult(ClientData &data)
|
|||||||
void
|
void
|
||||||
ResolverThread::Main()
|
ResolverThread::Main()
|
||||||
{
|
{
|
||||||
const ClientData &data = GetData();
|
const ClientContext &context = GetContext();
|
||||||
|
|
||||||
// Convert the port to a string.
|
// Convert the port to a string.
|
||||||
ostringstream tmpStr;
|
ostringstream tmpStr;
|
||||||
tmpStr << data.serverPort;
|
tmpStr << context.GetServerPort();
|
||||||
|
|
||||||
// Start the name resolution.
|
// Start the name resolution.
|
||||||
m_retVal = socket_resolve(
|
m_retVal = socket_resolve(
|
||||||
data.serverAddr.c_str(),
|
context.GetServerAddr().c_str(),
|
||||||
tmpStr.str().c_str(),
|
tmpStr.str().c_str(),
|
||||||
data.addrFamily,
|
context.GetAddrFamily(),
|
||||||
SOCK_STREAM,
|
SOCK_STREAM,
|
||||||
0,
|
0,
|
||||||
(struct sockaddr *)&data.clientAddr,
|
(struct sockaddr *)context.GetClientSockaddr(),
|
||||||
data.GetServerAddrSize());
|
context.GetClientSockaddrSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClientData &
|
const ClientContext &
|
||||||
ResolverThread::GetData() const
|
ResolverThread::GetContext() const
|
||||||
{
|
{
|
||||||
assert(m_data.get());
|
assert(m_context.get());
|
||||||
return *m_data;
|
return *m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientData &
|
ClientContext &
|
||||||
ResolverThread::GetData()
|
ResolverThread::GetContext()
|
||||||
{
|
{
|
||||||
assert(m_data.get());
|
assert(m_context.get());
|
||||||
return *m_data;
|
return *m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/sendercallback.h>
|
||||||
|
|
||||||
|
|
||||||
|
SenderCallback::~SenderCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <net/senderthread.h>
|
#include <net/senderthread.h>
|
||||||
#include <net/netcallback.h>
|
#include <net/sendercallback.h>
|
||||||
#include <net/socket_msg.h>
|
#include <net/socket_msg.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@ using namespace std;
|
|||||||
|
|
||||||
#define SEND_TIMEOUT_MSEC 50
|
#define SEND_TIMEOUT_MSEC 50
|
||||||
|
|
||||||
SenderThread::SenderThread(NetCallback &cb)
|
SenderThread::SenderThread(SenderCallback &cb)
|
||||||
: m_tmpOutBufSize(0), m_callback(cb)
|
: m_curSocket(INVALID_SOCKET), m_tmpOutBufSize(0), m_callback(cb)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,19 +36,13 @@ SenderThread::~SenderThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SenderThread::Init(SOCKET socket)
|
SenderThread::Send(boost::shared_ptr<NetPacket> packet, SOCKET sock)
|
||||||
{
|
{
|
||||||
if (!IS_VALID_SOCKET(socket) || IsRunning())
|
if (packet.get() && IS_VALID_SOCKET(sock))
|
||||||
return; // TODO: throw exception
|
|
||||||
|
|
||||||
m_socket = socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SenderThread::Send(boost::shared_ptr<NetPacket> packet)
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_outBufMutex);
|
boost::mutex::scoped_lock lock(m_outBufMutex);
|
||||||
m_outBuf.push_back(packet);
|
m_outBuf.push_back(std::make_pair(packet, sock));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -61,22 +55,26 @@ SenderThread::Main()
|
|||||||
// For reasons of simplicity, only one packet is sent at a time.
|
// For reasons of simplicity, only one packet is sent at a time.
|
||||||
if (!m_tmpOutBufSize)
|
if (!m_tmpOutBufSize)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<NetPacket> tmpPacket;
|
SendData tmpData;
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_outBufMutex);
|
boost::mutex::scoped_lock lock(m_outBufMutex);
|
||||||
if (!m_outBuf.empty())
|
if (!m_outBuf.empty())
|
||||||
{
|
{
|
||||||
tmpPacket = m_outBuf.front();
|
tmpData = m_outBuf.front();
|
||||||
m_outBuf.pop_front();
|
m_outBuf.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tmpPacket.get())
|
|
||||||
|
if (tmpData.first.get())
|
||||||
{
|
{
|
||||||
u_int16_t tmpLen = ntohs(tmpPacket->GetData()->length);
|
if (IS_VALID_SOCKET(tmpData.second))
|
||||||
|
m_curSocket = tmpData.second;
|
||||||
|
|
||||||
|
u_int16_t tmpLen = ntohs(tmpData.first->GetData()->length);
|
||||||
if (tmpLen <= MAX_PACKET_SIZE)
|
if (tmpLen <= MAX_PACKET_SIZE)
|
||||||
{
|
{
|
||||||
m_tmpOutBufSize = tmpLen;
|
m_tmpOutBufSize = tmpLen;
|
||||||
memcpy(m_tmpOutBuf, tmpPacket->GetData(), m_tmpOutBufSize);
|
memcpy(m_tmpOutBuf, tmpData.first->GetData(), m_tmpOutBufSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,25 +84,25 @@ SenderThread::Main()
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
FD_ZERO(&writeSet);
|
FD_ZERO(&writeSet);
|
||||||
FD_SET(m_socket, &writeSet);
|
FD_SET(m_curSocket, &writeSet);
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = SEND_TIMEOUT_MSEC * 1000;
|
timeout.tv_usec = SEND_TIMEOUT_MSEC * 1000;
|
||||||
int selectResult = select(m_socket + 1, NULL, &writeSet, NULL, &timeout);
|
int selectResult = select(m_curSocket + 1, NULL, &writeSet, NULL, &timeout);
|
||||||
if (!IS_VALID_SELECT(selectResult))
|
if (!IS_VALID_SELECT(selectResult))
|
||||||
{
|
{
|
||||||
m_callback.SignalNetError(ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
|
m_callback.SignalNetError(m_curSocket, ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
|
||||||
// Assume that this is a fatal error, terminate thread.
|
// Assume that this is a fatal error, terminate thread.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (selectResult > 0) // send is possible
|
if (selectResult > 0) // send is possible
|
||||||
{
|
{
|
||||||
// send next chunk of data
|
// send next chunk of data
|
||||||
int bytesSent = send(m_socket, m_tmpOutBuf, m_tmpOutBufSize, 0);
|
int bytesSent = send(m_curSocket, m_tmpOutBuf, m_tmpOutBufSize, 0);
|
||||||
|
|
||||||
if (!IS_VALID_SEND(bytesSent))
|
if (!IS_VALID_SEND(bytesSent))
|
||||||
{
|
{
|
||||||
m_callback.SignalNetError(ERR_SOCK_SEND_FAILED, SOCKET_ERRNO());
|
m_callback.SignalNetError(m_curSocket, ERR_SOCK_SEND_FAILED, SOCKET_ERRNO());
|
||||||
// Assume that this is a fatal error, terminate thread.
|
// Assume that this is a fatal error, terminate thread.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/servercontext.h>
|
||||||
|
|
||||||
|
ServerContext::ServerContext()
|
||||||
|
: m_sockfd(INVALID_SOCKET), m_addrFamily(AF_INET), m_serverPort(0)
|
||||||
|
{
|
||||||
|
bzero(&m_serverSockaddr, sizeof(m_serverSockaddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerContext::~ServerContext()
|
||||||
|
{
|
||||||
|
if (m_sockfd != INVALID_SOCKET)
|
||||||
|
CLOSESOCKET(m_sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET
|
||||||
|
ServerContext::GetSocket() const
|
||||||
|
{
|
||||||
|
return m_sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t
|
||||||
|
ServerContext::GetId() const
|
||||||
|
{
|
||||||
|
// Id is unused for main server thread.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerContext::SetSocket(SOCKET sockfd)
|
||||||
|
{
|
||||||
|
m_sockfd = sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/serverexception.h>
|
||||||
|
|
||||||
|
|
||||||
|
ServerException::~ServerException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/serverrecvstate.h>
|
||||||
|
#include <net/serverrecvthread.h>
|
||||||
|
#include <net/socket_msg.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define SERVER_WAIT_TIMEOUT_MSEC 50
|
||||||
|
|
||||||
|
|
||||||
|
ServerRecvState::~ServerRecvState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ServerRecvStateInit &
|
||||||
|
ServerRecvStateInit::Instance()
|
||||||
|
{
|
||||||
|
static ServerRecvStateInit state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerRecvStateInit::ServerRecvStateInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerRecvStateInit::~ServerRecvStateInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerRecvStateInit::HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ServerRecvStateInit::Process(ServerRecvThread &server)
|
||||||
|
{
|
||||||
|
Thread::Msleep(SERVER_WAIT_TIMEOUT_MSEC);
|
||||||
|
return MSG_SOCK_INIT_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/serverrecvthread.h>
|
||||||
|
#include <net/serverexception.h>
|
||||||
|
#include <net/serverrecvstate.h>
|
||||||
|
#include <net/senderthread.h>
|
||||||
|
#include <net/sendercallback.h>
|
||||||
|
#include <net/receiverhelper.h>
|
||||||
|
#include <net/socket_msg.h>
|
||||||
|
|
||||||
|
class ServerSenderCallback : public SenderCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServerSenderCallback(ServerRecvThread &server) : m_server(server) {}
|
||||||
|
virtual ~ServerSenderCallback() {}
|
||||||
|
|
||||||
|
virtual void SignalNetError(SOCKET sock, int errorID, int osErrorID)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ServerRecvThread &m_server;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ServerRecvThread::ServerRecvThread()
|
||||||
|
{
|
||||||
|
m_senderCallback.reset(new ServerSenderCallback(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerRecvThread::~ServerRecvThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerRecvThread::AddConnection(boost::shared_ptr<ConnectData> data)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_connectQueueMutex);
|
||||||
|
m_connectQueue.push_back(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerRecvThread::Main()
|
||||||
|
{
|
||||||
|
SetState(SERVER_INITIAL_STATE::Instance());
|
||||||
|
|
||||||
|
m_sender.reset(new SenderThread(GetSenderCallback()));
|
||||||
|
m_receiver.reset(new ReceiverHelper);
|
||||||
|
GetSender().Run();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!ShouldTerminate())
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::shared_ptr<ConnectData> tmpData;
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_connectQueueMutex);
|
||||||
|
if (!m_connectQueue.empty())
|
||||||
|
{
|
||||||
|
tmpData = m_connectQueue.front();
|
||||||
|
m_connectQueue.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmpData.get())
|
||||||
|
GetState().HandleNewConnection(*this, tmpData);
|
||||||
|
}
|
||||||
|
GetState().Process(*this);
|
||||||
|
}
|
||||||
|
} catch (const NetException &)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
GetSender().SignalTermination();
|
||||||
|
GetSender().Join(SENDER_THREAD_TERMINATE_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerRecvState &
|
||||||
|
ServerRecvThread::GetState()
|
||||||
|
{
|
||||||
|
assert(m_curState);
|
||||||
|
return *m_curState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerRecvThread::SetState(ServerRecvState &newState)
|
||||||
|
{
|
||||||
|
m_curState = &newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
SenderThread &
|
||||||
|
ServerRecvThread::GetSender()
|
||||||
|
{
|
||||||
|
assert(m_sender.get());
|
||||||
|
return *m_sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiverHelper &
|
||||||
|
ServerRecvThread::GetReceiver()
|
||||||
|
{
|
||||||
|
assert(m_receiver.get());
|
||||||
|
return *m_receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSenderCallback &
|
||||||
|
ServerRecvThread::GetSenderCallback()
|
||||||
|
{
|
||||||
|
assert(m_senderCallback.get());
|
||||||
|
return *m_senderCallback;
|
||||||
|
}
|
||||||
|
|
||||||
+131
-28
@@ -18,11 +18,20 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <net/serverthread.h>
|
#include <net/serverthread.h>
|
||||||
|
#include <net/servercontext.h>
|
||||||
|
#include <net/connectdata.h>
|
||||||
|
#include <net/serverrecvthread.h>
|
||||||
#include <net/socket_helper.h>
|
#include <net/socket_helper.h>
|
||||||
|
#include <net/serverexception.h>
|
||||||
|
#include <net/socket_msg.h>
|
||||||
|
|
||||||
|
#define ACCEPT_TIMEOUT_MSEC 50
|
||||||
|
#define NET_SERVER_LISTEN_BACKLOG 5
|
||||||
|
|
||||||
|
|
||||||
ServerThread::ServerThread()
|
ServerThread::ServerThread()
|
||||||
{
|
{
|
||||||
|
m_context.reset(new ServerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerThread::~ServerThread()
|
ServerThread::~ServerThread()
|
||||||
@@ -30,44 +39,138 @@ ServerThread::~ServerThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerThread::Init()
|
ServerThread::Init(unsigned serverPort, bool ipv6, const std::string &pwd)
|
||||||
{
|
{
|
||||||
if (IsRunning())
|
if (IsRunning())
|
||||||
return; // TODO: throw exception
|
return; // TODO: throw exception
|
||||||
|
|
||||||
|
ServerContext &context = GetContext();
|
||||||
|
|
||||||
|
context.SetAddrFamily(ipv6 ? AF_INET6 : AF_INET);
|
||||||
|
context.SetServerPort(serverPort);
|
||||||
|
context.SetPassword(pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerThread::Main()
|
ServerThread::Main()
|
||||||
{
|
{
|
||||||
|
m_recvThread.reset(new ServerRecvThread);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Listen();
|
||||||
|
GetRecvThread().Run();
|
||||||
|
|
||||||
while (!ShouldTerminate())
|
while (!ShouldTerminate())
|
||||||
{
|
{
|
||||||
// Simple hacked server for testing.
|
// The main server thread is simple. It only accepts connections.
|
||||||
SOCKET sockfd;
|
AcceptLoop();
|
||||||
char buf[1024];
|
}
|
||||||
struct sockaddr_storage servaddr, clientaddr;
|
} catch (const NetException &)
|
||||||
int sockaddr_size = sizeof(struct sockaddr_in);
|
{
|
||||||
int addrFamily = AF_INET;
|
// TODO: callback.
|
||||||
socklen_t addrSize;
|
|
||||||
|
|
||||||
sockfd = socket(addrFamily, SOCK_STREAM, 0);
|
|
||||||
bzero(&servaddr, sizeof(servaddr));
|
|
||||||
servaddr.ss_family = addrFamily;
|
|
||||||
|
|
||||||
socket_string_to_addr("0.0.0.0", addrFamily, (struct sockaddr *)&servaddr, sockaddr_size);
|
|
||||||
socket_set_port(7234, addrFamily, (struct sockaddr *)&servaddr, sockaddr_size);
|
|
||||||
|
|
||||||
bind(sockfd, (const struct sockaddr *)&servaddr, sockaddr_size);
|
|
||||||
listen(sockfd, 1);
|
|
||||||
|
|
||||||
bzero(&clientaddr, sizeof(clientaddr));
|
|
||||||
addrSize = sockaddr_size;
|
|
||||||
SOCKET conn = accept(sockfd, (struct sockaddr *)&clientaddr, &addrSize);
|
|
||||||
CLOSESOCKET(sockfd);
|
|
||||||
int ret = recv(conn, buf, sizeof(buf), 0);
|
|
||||||
|
|
||||||
send(conn, buf, ret, 0);
|
|
||||||
|
|
||||||
CLOSESOCKET(conn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerThread::Listen()
|
||||||
|
{
|
||||||
|
ServerContext &context = GetContext();
|
||||||
|
|
||||||
|
// if (context.GetServerPort() < 1024)
|
||||||
|
// throw ServerException(ERR_SOCK_INVALID_PORT, 0);
|
||||||
|
|
||||||
|
context.SetSocket(socket(context.GetAddrFamily(), SOCK_STREAM, 0));
|
||||||
|
if (!IS_VALID_SOCKET(context.GetSocket()))
|
||||||
|
throw ServerException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
||||||
|
|
||||||
|
unsigned long mode = 1;
|
||||||
|
if (IOCTLSOCKET(context.GetSocket(), FIONBIO, &mode) == SOCKET_ERROR)
|
||||||
|
throw ServerException(ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
|
||||||
|
|
||||||
|
context.GetServerSockaddr()->ss_family = context.GetAddrFamily();
|
||||||
|
|
||||||
|
if (!socket_string_to_addr(
|
||||||
|
"0.0.0.0",
|
||||||
|
context.GetAddrFamily(),
|
||||||
|
(struct sockaddr *)context.GetServerSockaddr(),
|
||||||
|
context.GetServerSockaddrSize()))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_SET_ADDR_FAILED, 0);
|
||||||
|
}
|
||||||
|
if (!socket_set_port(
|
||||||
|
context.GetServerPort(),
|
||||||
|
context.GetAddrFamily(),
|
||||||
|
(struct sockaddr *)context.GetServerSockaddr(),
|
||||||
|
context.GetServerSockaddrSize()))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_SET_PORT_FAILED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_VALID_BIND(bind(
|
||||||
|
context.GetSocket(),
|
||||||
|
(const struct sockaddr *)context.GetServerSockaddr(),
|
||||||
|
context.GetServerSockaddrSize())))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_BIND_FAILED, SOCKET_ERRNO());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_VALID_LISTEN(listen(context.GetSocket(), NET_SERVER_LISTEN_BACKLOG)))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_LISTEN_FAILED, SOCKET_ERRNO());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerThread::AcceptLoop()
|
||||||
|
{
|
||||||
|
ServerContext &context = GetContext();
|
||||||
|
|
||||||
|
fd_set readSet;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
FD_ZERO(&readSet);
|
||||||
|
FD_SET(context.GetSocket(), &readSet);
|
||||||
|
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = ACCEPT_TIMEOUT_MSEC * 1000;
|
||||||
|
int selectResult = select(context.GetSocket() + 1, &readSet, NULL, NULL, &timeout);
|
||||||
|
if (!IS_VALID_SELECT(selectResult))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_SELECT_FAILED, SOCKET_ERRNO());
|
||||||
|
}
|
||||||
|
if (selectResult > 0) // accept is possible
|
||||||
|
{
|
||||||
|
boost::shared_ptr<ConnectData> tmpData(new ConnectData);
|
||||||
|
socklen_t addrSize = sizeof(*tmpData->GetSockaddr());
|
||||||
|
tmpData->SetSocket(accept(context.GetSocket(), (struct sockaddr *)tmpData->GetSockaddr(), &addrSize));
|
||||||
|
|
||||||
|
if (!IS_VALID_SOCKET(tmpData->GetSocket()))
|
||||||
|
{
|
||||||
|
throw ServerException(ERR_SOCK_ACCEPT_FAILED, SOCKET_ERRNO());
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRecvThread().AddConnection(tmpData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ServerContext &
|
||||||
|
ServerThread::GetContext() const
|
||||||
|
{
|
||||||
|
assert(m_context.get());
|
||||||
|
return *m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerContext &
|
||||||
|
ServerThread::GetContext()
|
||||||
|
{
|
||||||
|
assert(m_context.get());
|
||||||
|
return *m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerRecvThread &
|
||||||
|
ServerThread::GetRecvThread()
|
||||||
|
{
|
||||||
|
assert(m_recvThread.get());
|
||||||
|
return *m_recvThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Connection data. */
|
||||||
|
|
||||||
|
#ifndef _CONNECTDATA_H_
|
||||||
|
#define _CONNECTDATA_H_
|
||||||
|
|
||||||
|
#include <net/socket_helper.h>
|
||||||
|
|
||||||
|
class ConnectData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConnectData();
|
||||||
|
~ConnectData();
|
||||||
|
|
||||||
|
SOCKET GetSocket() const
|
||||||
|
{return m_sockfd;}
|
||||||
|
void SetSocket(SOCKET sockfd)
|
||||||
|
{m_sockfd = sockfd;}
|
||||||
|
const sockaddr_storage *GetSockaddr() const
|
||||||
|
{return &m_sockaddr;}
|
||||||
|
sockaddr_storage *GetSockaddr()
|
||||||
|
{return &m_sockaddr;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SOCKET m_sockfd;
|
||||||
|
sockaddr_storage m_sockaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,31 +16,22 @@
|
|||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
/* State of network client. */
|
/* Network context data. */
|
||||||
|
|
||||||
#ifndef _CLIENTDATA_H_
|
#ifndef _NETCONTEXT_H_
|
||||||
#define _CLIENTDATA_H_
|
#define _NETCONTEXT_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <net/socket_helper.h>
|
#include <net/socket_helper.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
class ClientData
|
class NetContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClientData();
|
virtual ~NetContext();
|
||||||
~ClientData();
|
|
||||||
int GetServerAddrSize() const
|
|
||||||
{
|
|
||||||
return addrFamily == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
SOCKET sockfd;
|
virtual SOCKET GetSocket() const = 0;
|
||||||
int addrFamily;
|
virtual u_int32_t GetId() const = 0;
|
||||||
std::string serverAddr;
|
|
||||||
unsigned serverPort;
|
|
||||||
std::string password;
|
|
||||||
sockaddr_storage clientAddr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
// MUST be larger than MAX_PACKET_SIZE
|
// MUST be larger than MAX_PACKET_SIZE
|
||||||
#define RECV_BUF_SIZE 10 * MAX_PACKET_SIZE
|
#define RECV_BUF_SIZE 10 * MAX_PACKET_SIZE
|
||||||
|
|
||||||
|
|
||||||
class ReceiverHelper
|
class ReceiverHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -39,7 +40,7 @@ public:
|
|||||||
// Set the socket from which to receive data.
|
// Set the socket from which to receive data.
|
||||||
void Init(SOCKET socket);
|
void Init(SOCKET socket);
|
||||||
|
|
||||||
boost::shared_ptr<NetPacket> Recv();
|
boost::shared_ptr<NetPacket> Recv(SOCKET sock);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boost::shared_ptr<NetPacket> InternalGetPacket();
|
boost::shared_ptr<NetPacket> InternalGetPacket();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class ClientData;
|
class ClientContext;
|
||||||
|
|
||||||
class ResolverThread : public Thread
|
class ResolverThread : public Thread
|
||||||
{
|
{
|
||||||
@@ -36,24 +36,24 @@ public:
|
|||||||
// Set the parameters. Does not do any error checking.
|
// Set the parameters. Does not do any error checking.
|
||||||
// To prevent access faults if this thread cannot be
|
// To prevent access faults if this thread cannot be
|
||||||
// terminated, the data is not modified.
|
// terminated, the data is not modified.
|
||||||
void Init(const ClientData &data);
|
void Init(const ClientContext &context);
|
||||||
|
|
||||||
// Retrieve the result of the name resolution.
|
// Retrieve the result of the name resolution.
|
||||||
// ONLY CALL THIS FUNCTION AFTER THE THREAD TERMINATED.
|
// ONLY CALL THIS FUNCTION AFTER THE THREAD TERMINATED.
|
||||||
// You have been warned...
|
// You have been warned...
|
||||||
bool GetResult(ClientData &data);
|
bool GetResult(ClientContext &context) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Main function of the thread.
|
// Main function of the thread.
|
||||||
virtual void Main();
|
virtual void Main();
|
||||||
|
|
||||||
const ClientData &GetData() const;
|
const ClientContext &GetContext() const;
|
||||||
ClientData &GetData();
|
ClientContext &GetContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::auto_ptr<ClientData> m_data;
|
std::auto_ptr<ClientContext> m_context;
|
||||||
bool m_retVal;
|
bool m_retVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Callback interface for the sender thread. */
|
||||||
|
|
||||||
|
#ifndef _SENDERCALLBACK_H_
|
||||||
|
#define _SENDERCALLBACK_H_
|
||||||
|
|
||||||
|
#include <net/socket_helper.h>
|
||||||
|
|
||||||
|
class SenderCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SenderCallback();
|
||||||
|
|
||||||
|
virtual void SignalNetError(SOCKET sock, int errorID, int osErrorID) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -24,22 +24,20 @@
|
|||||||
#include <core/thread.h>
|
#include <core/thread.h>
|
||||||
#include <net/socket_helper.h>
|
#include <net/socket_helper.h>
|
||||||
#include <net/netpacket.h>
|
#include <net/netpacket.h>
|
||||||
|
#include <net/sendercallback.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
class NetCallback;
|
#define SENDER_THREAD_TERMINATE_TIMEOUT 100
|
||||||
|
|
||||||
class SenderThread : public Thread
|
class SenderThread : public Thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SenderThread(NetCallback &cb);
|
SenderThread(SenderCallback &cb);
|
||||||
virtual ~SenderThread();
|
virtual ~SenderThread();
|
||||||
|
|
||||||
// Set the socket used to send data.
|
void Send(boost::shared_ptr<NetPacket> packet, SOCKET sock);
|
||||||
void Init(SOCKET socket);
|
|
||||||
|
|
||||||
void Send(boost::shared_ptr<NetPacket> packet);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -48,15 +46,16 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SOCKET m_socket;
|
SOCKET m_curSocket;
|
||||||
|
|
||||||
std::deque<boost::shared_ptr<NetPacket> > m_outBuf;
|
typedef std::pair<boost::shared_ptr<NetPacket>, SOCKET> SendData;
|
||||||
|
std::deque<SendData> m_outBuf;
|
||||||
mutable boost::mutex m_outBufMutex;
|
mutable boost::mutex m_outBufMutex;
|
||||||
|
|
||||||
char m_tmpOutBuf[MAX_PACKET_SIZE];
|
char m_tmpOutBuf[MAX_PACKET_SIZE];
|
||||||
unsigned m_tmpOutBufSize;
|
unsigned m_tmpOutBufSize;
|
||||||
|
|
||||||
NetCallback &m_callback;
|
SenderCallback &m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Context of network server. */
|
||||||
|
|
||||||
|
#ifndef _SERVERCONTEXT_H_
|
||||||
|
#define _SERVERCONTEXT_H_
|
||||||
|
|
||||||
|
#include <net/netcontext.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ServerContext : public NetContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServerContext();
|
||||||
|
virtual ~ServerContext();
|
||||||
|
|
||||||
|
virtual SOCKET GetSocket() const;
|
||||||
|
virtual u_int32_t GetId() const;
|
||||||
|
|
||||||
|
void SetSocket(SOCKET sockfd);
|
||||||
|
|
||||||
|
int GetAddrFamily() const
|
||||||
|
{return m_addrFamily;}
|
||||||
|
void SetAddrFamily(int addrFamily)
|
||||||
|
{m_addrFamily = addrFamily;}
|
||||||
|
unsigned GetServerPort() const
|
||||||
|
{return m_serverPort;}
|
||||||
|
void SetServerPort(unsigned serverPort)
|
||||||
|
{m_serverPort = serverPort;}
|
||||||
|
const std::string &GetPassword() const
|
||||||
|
{return m_password;}
|
||||||
|
void SetPassword(const std::string &password)
|
||||||
|
{m_password = password;}
|
||||||
|
const sockaddr_storage *GetServerSockaddr() const
|
||||||
|
{return &m_serverSockaddr;}
|
||||||
|
sockaddr_storage *GetServerSockaddr()
|
||||||
|
{return &m_serverSockaddr;}
|
||||||
|
|
||||||
|
int GetServerSockaddrSize() const
|
||||||
|
{return m_addrFamily == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SOCKET m_sockfd;
|
||||||
|
int m_addrFamily;
|
||||||
|
unsigned m_serverPort;
|
||||||
|
std::string m_password;
|
||||||
|
sockaddr_storage m_serverSockaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Exception class for server errors. */
|
||||||
|
|
||||||
|
#ifndef _SERVEREXCEPTION_H_
|
||||||
|
#define _SERVEREXCEPTION_H_
|
||||||
|
|
||||||
|
#include <net/netexception.h>
|
||||||
|
|
||||||
|
class ServerException : public NetException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ServerException(int errorId, int osErrorCode)
|
||||||
|
: NetException(errorId, osErrorCode) {}
|
||||||
|
|
||||||
|
virtual ~ServerException();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* State of network server. */
|
||||||
|
|
||||||
|
#ifndef _SERVERRECVSTATE_H_
|
||||||
|
#define _SERVERRECVSTATE_H_
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <net/connectdata.h>
|
||||||
|
|
||||||
|
#define SERVER_INITIAL_STATE ServerRecvStateInit
|
||||||
|
|
||||||
|
class ServerRecvThread;
|
||||||
|
class ServerCallback;
|
||||||
|
|
||||||
|
class ServerRecvState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ServerRecvState();
|
||||||
|
|
||||||
|
// Handling of a new TCP connection.
|
||||||
|
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data) = 0;
|
||||||
|
|
||||||
|
// Main processing function of the current state.
|
||||||
|
virtual int Process(ServerRecvThread &server) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// State: Initialization.
|
||||||
|
class ServerRecvStateInit : public ServerRecvState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Access the state singleton.
|
||||||
|
static ServerRecvStateInit &Instance();
|
||||||
|
|
||||||
|
virtual ~ServerRecvStateInit();
|
||||||
|
|
||||||
|
//
|
||||||
|
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
|
||||||
|
|
||||||
|
//
|
||||||
|
virtual int Process(ServerRecvThread &server);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected constructor - this is a singleton.
|
||||||
|
ServerRecvStateInit();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Lothar May *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Network server receive thread. */
|
||||||
|
|
||||||
|
#ifndef _SERVERRECVTHREAD_H_
|
||||||
|
#define _SERVERRECVTHREAD_H_
|
||||||
|
|
||||||
|
#include <core/thread.h>
|
||||||
|
#include <deque>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include <net/connectdata.h>
|
||||||
|
|
||||||
|
class ServerRecvState;
|
||||||
|
class SenderThread;
|
||||||
|
class ReceiverHelper;
|
||||||
|
class ServerSenderCallback;
|
||||||
|
|
||||||
|
class ServerRecvThread : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ServerRecvThread();
|
||||||
|
virtual ~ServerRecvThread();
|
||||||
|
|
||||||
|
void AddConnection(boost::shared_ptr<ConnectData> data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Main function of the thread.
|
||||||
|
virtual void Main();
|
||||||
|
|
||||||
|
ServerRecvState &GetState();
|
||||||
|
void SetState(ServerRecvState &newState);
|
||||||
|
|
||||||
|
//const ServerRecvContext &GetContext() const;
|
||||||
|
//ServerRecvContext &GetContext();
|
||||||
|
|
||||||
|
SenderThread &GetSender();
|
||||||
|
ReceiverHelper &GetReceiver();
|
||||||
|
|
||||||
|
ServerSenderCallback &GetSenderCallback();
|
||||||
|
|
||||||
|
private:
|
||||||
|
//std::auto_ptr<ServerRecvContext> m_context;
|
||||||
|
|
||||||
|
std::deque<boost::shared_ptr<ConnectData> > m_connectQueue;
|
||||||
|
mutable boost::mutex m_connectQueueMutex;
|
||||||
|
ServerRecvState *m_curState;
|
||||||
|
|
||||||
|
std::auto_ptr<ReceiverHelper> m_receiver;
|
||||||
|
std::auto_ptr<SenderThread> m_sender;
|
||||||
|
|
||||||
|
std::auto_ptr<ServerSenderCallback> m_senderCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+16
-3
@@ -25,6 +25,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class ServerContext;
|
||||||
|
class ServerRecvThread;
|
||||||
|
class ServerSenderCallback;
|
||||||
|
class SenderThread;
|
||||||
|
|
||||||
class ServerThread : public Thread
|
class ServerThread : public Thread
|
||||||
{
|
{
|
||||||
@@ -32,16 +36,25 @@ public:
|
|||||||
ServerThread(/*ServerCallback &gui*/);
|
ServerThread(/*ServerCallback &gui*/);
|
||||||
virtual ~ServerThread();
|
virtual ~ServerThread();
|
||||||
|
|
||||||
// Set the parameters. TODO
|
// Set the parameters.
|
||||||
void Init();
|
void Init(unsigned serverPort, bool ipv6, const std::string &pwd);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Main function of the thread.
|
// Main function of the thread.
|
||||||
virtual void Main();
|
virtual void Main();
|
||||||
|
|
||||||
private:
|
void Listen();
|
||||||
|
void AcceptLoop();
|
||||||
|
|
||||||
|
const ServerContext &GetContext() const;
|
||||||
|
ServerContext &GetContext();
|
||||||
|
|
||||||
|
ServerRecvThread &GetRecvThread();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::auto_ptr<ServerContext> m_context;
|
||||||
|
std::auto_ptr<ServerRecvThread> m_recvThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ typedef unsigned char u_char;
|
|||||||
#define IS_VALID_SOCKET(_s) ((_s) != INVALID_SOCKET)
|
#define IS_VALID_SOCKET(_s) ((_s) != INVALID_SOCKET)
|
||||||
#define IS_VALID_CONNECT(_c) ((_c) == 0)
|
#define IS_VALID_CONNECT(_c) ((_c) == 0)
|
||||||
#define IS_VALID_BIND(_b) ((_b) != SOCKET_ERROR)
|
#define IS_VALID_BIND(_b) ((_b) != SOCKET_ERROR)
|
||||||
|
#define IS_VALID_LISTEN(_l) ((_l) != SOCKET_ERROR)
|
||||||
#define IS_VALID_RECV(_r) ((_r) != SOCKET_ERROR)
|
#define IS_VALID_RECV(_r) ((_r) != SOCKET_ERROR)
|
||||||
#define IS_VALID_SEND(_s) ((_s) != SOCKET_ERROR)
|
#define IS_VALID_SEND(_s) ((_s) != SOCKET_ERROR)
|
||||||
#define IS_VALID_SELECT(_s) ((_s) != SOCKET_ERROR)
|
#define IS_VALID_SELECT(_s) ((_s) != SOCKET_ERROR)
|
||||||
|
|||||||
+11
-7
@@ -24,13 +24,17 @@
|
|||||||
#define ERR_SOCK_SERVERADDR_NOT_SET 2
|
#define ERR_SOCK_SERVERADDR_NOT_SET 2
|
||||||
#define ERR_SOCK_INVALID_PORT 3
|
#define ERR_SOCK_INVALID_PORT 3
|
||||||
#define ERR_SOCK_CREATION_FAILED 4
|
#define ERR_SOCK_CREATION_FAILED 4
|
||||||
#define ERR_SOCK_SET_PORT_FAILED 5
|
#define ERR_SOCK_SET_ADDR_FAILED 5
|
||||||
#define ERR_SOCK_RESOLVE_FAILED 6
|
#define ERR_SOCK_SET_PORT_FAILED 6
|
||||||
#define ERR_SOCK_CONNECT_FAILED 7
|
#define ERR_SOCK_RESOLVE_FAILED 7
|
||||||
#define ERR_SOCK_SELECT_FAILED 8
|
#define ERR_SOCK_BIND_FAILED 8
|
||||||
#define ERR_SOCK_RECV_FAILED 9
|
#define ERR_SOCK_LISTEN_FAILED 9
|
||||||
#define ERR_SOCK_SEND_FAILED 10
|
#define ERR_SOCK_ACCEPT_FAILED 10
|
||||||
#define ERR_SOCK_CONN_RESET 11
|
#define ERR_SOCK_CONNECT_FAILED 11
|
||||||
|
#define ERR_SOCK_SELECT_FAILED 12
|
||||||
|
#define ERR_SOCK_RECV_FAILED 13
|
||||||
|
#define ERR_SOCK_SEND_FAILED 14
|
||||||
|
#define ERR_SOCK_CONN_RESET 15
|
||||||
|
|
||||||
// This is an internal message which is not reported.
|
// This is an internal message which is not reported.
|
||||||
#define MSG_SOCK_INTERNAL_PENDING 0
|
#define MSG_SOCK_INTERNAL_PENDING 0
|
||||||
|
|||||||
+4
-1
@@ -86,7 +86,10 @@ void Session::startNetworkServer()
|
|||||||
if (myNetServer)
|
if (myNetServer)
|
||||||
return; // TODO: throw exception
|
return; // TODO: throw exception
|
||||||
myNetServer = new ServerThread();
|
myNetServer = new ServerThread();
|
||||||
myNetServer->Init();
|
myNetServer->Init(
|
||||||
|
myConfig->readConfigInt("ServerPort"),
|
||||||
|
myConfig->readConfigInt("ServerUseIpv6") == 1,
|
||||||
|
"");
|
||||||
myNetServer->Run();
|
myNetServer->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user