net code imported
This commit is contained in:
parent
5710e9b818
commit
b7c9226183
170
src/ZE_ZClient.cpp
Executable file
170
src/ZE_ZClient.cpp
Executable file
@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
This file is Part of the ZEngine Library for 2D game development.
|
||||
Copyright (C) 2002, 2003 James Turk
|
||||
|
||||
Licensed under a BSD-style license.
|
||||
|
||||
The maintainer of this library is James Turk (james@conceptofzero.net)
|
||||
and the home of this Library is http://www.zengine.sourceforge.net
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\par File Header:
|
||||
File: ZE_ZClient.cpp <br>
|
||||
Description: Implementation source file for core ZEngine TCP Client Object. <br>
|
||||
Author(s): James Turk <br>
|
||||
$Id:<br>
|
||||
|
||||
\file ZE_ZClient.cpp
|
||||
\brief Source file for ZClient.
|
||||
|
||||
Implementation file for ZClient, the TCP Client class for ZEngine.
|
||||
**/
|
||||
|
||||
#include "ZE_ZClient.h"
|
||||
|
||||
namespace ZE
|
||||
{
|
||||
|
||||
string num2dotted4(unsigned int num)
|
||||
{
|
||||
vector<int> ip;
|
||||
int d=256*256*256;
|
||||
int m;
|
||||
|
||||
while(d > 0)
|
||||
{
|
||||
m = num/d;
|
||||
num %= d;
|
||||
ip.push_back(m);
|
||||
d /= 256;
|
||||
}
|
||||
|
||||
return FormatStr("%d.%d.%d.%d",ip[3],ip[2],ip[1],ip[0]);
|
||||
}
|
||||
|
||||
ZClient::ZClient(bool verbose)
|
||||
{
|
||||
rEngine = ZEngine::GetInstance();
|
||||
rSocket = NULL;
|
||||
rSocketSet = NULL;
|
||||
rVerbose = verbose;
|
||||
rWaitTime = 0;
|
||||
}
|
||||
|
||||
ZClient::~ZClient()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
bool ZClient::Connect(char *server, Uint16 port)
|
||||
{
|
||||
IPaddress ip;
|
||||
|
||||
if(SDLNet_ResolveHost(&ip,server,port) < 0)
|
||||
rEngine->ReportError(ZERR_NET_CLIENT,FormatStr("Failed to resolve host: %s:%d",server,port));
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZClient: resolved host: %s:%d",server,port));
|
||||
|
||||
rEngine->WriteLog(FormatStr("IP: %s",num2dotted4(ip.host).c_str()));
|
||||
|
||||
rSocket = SDLNet_TCP_Open(&ip); //try to open rSocket
|
||||
|
||||
if(!rSocket)
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_CLIENT,"Failed to open TCP socket.");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
rSocketSet = SDLNet_AllocSocketSet(1); //get a set for the single socket
|
||||
if(!rSocketSet || SDLNet_TCP_AddSocket(rSocketSet,rSocket) == -1)
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_CLIENT,"Failed to create socket set.");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZClient::Disconnect()
|
||||
{
|
||||
if(rSocket)
|
||||
{
|
||||
SDLNet_TCP_Close(rSocket);
|
||||
rSocket = NULL;
|
||||
}
|
||||
if(rSocketSet)
|
||||
{
|
||||
SDLNet_FreeSocketSet(rSocketSet);
|
||||
rSocketSet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ZClient::SetWaitTime(int wait)
|
||||
{
|
||||
rWaitTime = wait;
|
||||
}
|
||||
|
||||
bool ZClient::Send(ZByte *data, int size)
|
||||
{
|
||||
int sent = 0;
|
||||
|
||||
if(rSocket)
|
||||
{
|
||||
sent = SDLNet_TCP_Send(rSocket,data,size);
|
||||
|
||||
if(sent < size)
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_CLIENT,FormatStr("Failed to send data, closing socket: %s", SDLNet_GetError()));
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZClient: Sent %d bytes to server.",sent));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rEngine->ReportError(ZERR_NOSOCKET,"Send");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ZClient::Receive(ZByte *data)
|
||||
{
|
||||
int received = 0;
|
||||
|
||||
if(rSocket)
|
||||
{
|
||||
if(SDLNet_CheckSockets(rSocketSet, rWaitTime) > 0 && SDLNet_SocketReady(rSocket))
|
||||
{
|
||||
received = SDLNet_TCP_Recv(rSocket,data,MAX_MSG_LEN);
|
||||
if(received <= 0)
|
||||
{
|
||||
Disconnect();
|
||||
rEngine->ReportError(ZERR_NET_CLIENT,FormatStr("TCP_Recv failed [%s]",SDLNet_GetError()));
|
||||
}
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZClient: received %d bytes.",received));
|
||||
}
|
||||
}
|
||||
else
|
||||
rEngine->ReportError(ZERR_NOSOCKET,"Receive");
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
bool ZClient::Connected()
|
||||
{
|
||||
return rSocket?true:false;
|
||||
}
|
||||
|
||||
int ZClient::WaitTime()
|
||||
{
|
||||
return rWaitTime;
|
||||
}
|
||||
|
||||
} //namespace ZE
|
196
src/ZE_ZServer.cpp
Executable file
196
src/ZE_ZServer.cpp
Executable file
@ -0,0 +1,196 @@
|
||||
/*******************************************************************************
|
||||
This file is Part of the ZEngine Library for 2D game development.
|
||||
Copyright (C) 2002, 2003 James Turk
|
||||
|
||||
Licensed under a BSD-style license.
|
||||
|
||||
The maintainer of this library is James Turk (james@conceptofzero.net)
|
||||
and the home of this Library is http://www.zengine.sourceforge.net
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\par File Header:
|
||||
File: ZE_ZServer.cpp <br>
|
||||
Description: Implementation source file for core ZEngine TCP Server Object. <br>
|
||||
Author(s): James Turk <br>
|
||||
$Id:<br>
|
||||
|
||||
\file ZE_ZServer.cpp
|
||||
\brief Source file for ZServer.
|
||||
|
||||
Implementation file for ZServer, the TCP Server class for ZEngine.
|
||||
**/
|
||||
|
||||
#include "ZE_ZServer.h"
|
||||
|
||||
namespace ZE
|
||||
{
|
||||
|
||||
void ZServer::CloseSocket(int num)
|
||||
{
|
||||
SDLNet_TCP_Close(rClientSockets[num]);
|
||||
rClientSockets[num] = NULL;
|
||||
if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("Closing socket #%d",num));
|
||||
}
|
||||
|
||||
ZServer::ZServer(bool v)
|
||||
{
|
||||
rEngine = ZEngine::GetInstance();
|
||||
|
||||
rSocket = NULL;
|
||||
rSocketSet = NULL;
|
||||
rClientSockets = NULL;
|
||||
rMaxClients = 0;
|
||||
rVerbose = v;
|
||||
rWaitTime = 0;
|
||||
}
|
||||
|
||||
ZServer::~ZServer()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
bool ZServer::Start(int maxClients, Uint16 port)
|
||||
{
|
||||
IPaddress ip;
|
||||
|
||||
rMaxClients = maxClients;
|
||||
rClientSockets = new TCPsocket[rMaxClients];
|
||||
|
||||
rSocketSet = SDLNet_AllocSocketSet(rMaxClients+1); //need one more (for server socket)
|
||||
if(!rSocketSet)
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_SERVER,FormatStr("Failed to create sockets (%s).",SDLNet_GetError()));
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZServer: Created server with %d available sockets.",rMaxClients));
|
||||
|
||||
for(int i=0; i < rMaxClients; i++)
|
||||
rClientSockets[i] = NULL;
|
||||
|
||||
if(SDLNet_ResolveHost(&ip,NULL,port) < 0) //try to resolve the host
|
||||
rEngine->ReportError(ZERR_NET_SERVER,FormatStr("Failed to create host server on port %d (%s).",port,SDLNet_GetError()));
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZServer: Created host server on port %d.",port));
|
||||
|
||||
rSocket = SDLNet_TCP_Open(&ip); //try to open socket
|
||||
if(!rSocket || SDLNet_TCP_AddSocket(rSocketSet,rSocket) == -1)
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_SERVER,"Failed to open server TCP socket.");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZServer::Stop()
|
||||
{
|
||||
if(rSocket)
|
||||
{
|
||||
SDLNet_TCP_Close(rSocket);
|
||||
rSocket = NULL;
|
||||
}
|
||||
if(rSocketSet)
|
||||
{
|
||||
SDLNet_FreeSocketSet(rSocketSet);
|
||||
rSocketSet = NULL;
|
||||
}
|
||||
if(rClientSockets)
|
||||
{
|
||||
for(int i=0; i < rMaxClients; i++)
|
||||
{
|
||||
if(rClientSockets[i])
|
||||
{
|
||||
CloseSocket(i);
|
||||
}
|
||||
}
|
||||
delete[] rClientSockets;
|
||||
}
|
||||
|
||||
rMaxClients = 0;
|
||||
}
|
||||
|
||||
void ZServer::SetWaitTime(int wait)
|
||||
{
|
||||
rWaitTime = wait;
|
||||
}
|
||||
|
||||
void ZServer::CheckSockets()
|
||||
{
|
||||
ZByte buf[MAX_MSG_LEN];
|
||||
int result,size,count;
|
||||
|
||||
SDLNet_CheckSockets(rSocketSet, rWaitTime);
|
||||
|
||||
if(SDLNet_SocketReady(rSocket)) //new client
|
||||
{
|
||||
for(count=0; count < rMaxClients; count++) //find first open socket
|
||||
{
|
||||
if(!rClientSockets[count])
|
||||
break;
|
||||
}
|
||||
|
||||
if(rClientSockets[count]) //if it exists the set is full
|
||||
{
|
||||
rEngine->ReportError(ZERR_NET_SERVER,FormatStr("All %d ports full.",rMaxClients));
|
||||
}
|
||||
else
|
||||
{
|
||||
rClientSockets[count] = SDLNet_TCP_Accept(rSocket);
|
||||
SDLNet_TCP_AddSocket(rSocketSet, rClientSockets[count]);
|
||||
if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZServer: Adding socket #%d.",count+1));
|
||||
}
|
||||
}
|
||||
|
||||
//check all sockets for activity//
|
||||
for(int i=0; i < rMaxClients; i++)
|
||||
{
|
||||
if(SDLNet_SocketReady(rClientSockets[i])) //incoming message
|
||||
{
|
||||
result = SDLNet_TCP_Recv(rClientSockets[i], buf, MAX_MSG_LEN);
|
||||
|
||||
if(result <= 0) //disconnect bad sockets
|
||||
CloseSocket(i);
|
||||
else if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr("ZServer: Received %d bytes on Port %d",result,i));
|
||||
|
||||
size = result;
|
||||
if(rVerbose)
|
||||
rEngine->WriteLog("ZServer: Mirroring data: ");
|
||||
for(int j=0; j < rMaxClients; j++)
|
||||
{
|
||||
if(rClientSockets[j] && i != j) //send to open sockets that aren't the same
|
||||
{
|
||||
result = SDLNet_TCP_Send(rClientSockets[j],buf,size);
|
||||
if(rVerbose)
|
||||
rEngine->WriteLog(FormatStr(" +%d bytes on socket %d.",size,j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ZServer::Clients()
|
||||
{
|
||||
int numClients=0;
|
||||
|
||||
for(int i=0; i < rMaxClients; i++)
|
||||
{
|
||||
if(rClientSockets[i])
|
||||
numClients++;
|
||||
}
|
||||
|
||||
return numClients;
|
||||
}
|
||||
|
||||
int ZServer::WaitTime()
|
||||
{
|
||||
return rWaitTime;
|
||||
}
|
||||
|
||||
} //namespace ZE
|
Loading…
Reference in New Issue
Block a user