mirror of
https://github.com/glest/glest-source.git
synced 2025-08-13 20:03:58 +02:00
Added auto-discovery of LAN servers using UDP broadcast. (for now the client must press the A key from the join menu to trigger this)
This commit is contained in:
@@ -232,7 +232,6 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
|
|||||||
bool bOkToStart = serverInterface->launchGame(&gameSettings);
|
bool bOkToStart = serverInterface->launchGame(&gameSettings);
|
||||||
if(bOkToStart == true)
|
if(bOkToStart == true)
|
||||||
{
|
{
|
||||||
|
|
||||||
program->setState(new Game(program, &gameSettings));
|
program->setState(new Game(program, &gameSettings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -336,11 +336,15 @@ void MenuStateJoinGame::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MenuStateJoinGame::keyDown(char key){
|
void MenuStateJoinGame::keyDown(char key){
|
||||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c][%d]\n",__FILE__,__FUNCTION__,__LINE__,key,key);
|
||||||
|
|
||||||
|
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||||
if(!clientInterface->isConnected())
|
if(!clientInterface->isConnected())
|
||||||
{
|
{
|
||||||
if(key==vkBack){
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
if(key==vkBack) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
string text= labelServerIp.getText();
|
string text= labelServerIp.getText();
|
||||||
|
|
||||||
if(text.size()>1){
|
if(text.size()>1){
|
||||||
@@ -349,9 +353,22 @@ void MenuStateJoinGame::keyDown(char key){
|
|||||||
|
|
||||||
labelServerIp.setText(text);
|
labelServerIp.setText(text);
|
||||||
}
|
}
|
||||||
|
else if(key== 'A') {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
std::vector<string> serverList = clientInterface->discoverServers();
|
||||||
|
if(serverList.size() > 0) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] serverList[0] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverList[0].c_str());
|
||||||
|
|
||||||
|
labelServerIp.setText(serverList[0]);
|
||||||
|
connectToServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
//send key to the chat manager
|
//send key to the chat manager
|
||||||
chatManager.keyDown(key);
|
chatManager.keyDown(key);
|
||||||
}
|
}
|
||||||
|
@@ -559,6 +559,17 @@ void ClientInterface::close()
|
|||||||
delete clientSocket;
|
delete clientSocket;
|
||||||
clientSocket= NULL;
|
clientSocket= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<string> ClientInterface::discoverServers() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
std::vector<string> serverList = ClientSocket::discoverServers();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
return serverList;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bool ClientInterface::getFogOfWar()
|
bool ClientInterface::getFogOfWar()
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
// This file is part of Glest (www.glest.org)
|
// This file is part of Glest (www.glest.org)
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
// Copyright (C) 2001-2008 Martio Figueroa
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
@@ -76,6 +76,8 @@ public:
|
|||||||
void connect(const Ip &ip, int port);
|
void connect(const Ip &ip, int port);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
std::vector<string> discoverServers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void waitForMessage();
|
void waitForMessage();
|
||||||
};
|
};
|
||||||
|
@@ -412,6 +412,8 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){
|
|||||||
|
|
||||||
if(bOkToStart == true)
|
if(bOkToStart == true)
|
||||||
{
|
{
|
||||||
|
serverSocket.stopBroadCastThread();
|
||||||
|
|
||||||
NetworkMessageLaunch networkMessageLaunch(gameSettings);
|
NetworkMessageLaunch networkMessageLaunch(gameSettings);
|
||||||
broadcastMessage(&networkMessageLaunch);
|
broadcastMessage(&networkMessageLaunch);
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
@@ -53,11 +55,16 @@ class Socket {
|
|||||||
protected:
|
protected:
|
||||||
int sock;
|
int sock;
|
||||||
long lastDebugEvent;
|
long lastDebugEvent;
|
||||||
|
static int broadcast_portno;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Socket(int sock);
|
Socket(int sock);
|
||||||
Socket();
|
Socket();
|
||||||
~Socket();
|
virtual ~Socket();
|
||||||
|
|
||||||
|
static int getBroadCastPort() { return broadcast_portno; }
|
||||||
|
static void setBroadCastPort(int value) { broadcast_portno = value; }
|
||||||
|
static std::vector<std::string> getLocalIPAddressList();
|
||||||
|
|
||||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||||
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
|
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
|
||||||
@@ -91,6 +98,28 @@ protected:
|
|||||||
class ClientSocket: public Socket{
|
class ClientSocket: public Socket{
|
||||||
public:
|
public:
|
||||||
void connect(const Ip &ip, int port);
|
void connect(const Ip &ip, int port);
|
||||||
|
|
||||||
|
static std::vector<string> discoverServers();
|
||||||
|
};
|
||||||
|
|
||||||
|
class BroadCastSocketThread : public Thread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Mutex mutexRunning;
|
||||||
|
Mutex mutexQuit;
|
||||||
|
|
||||||
|
bool quit;
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
void setRunningStatus(bool value);
|
||||||
|
void setQuitStatus(bool value);
|
||||||
|
|
||||||
|
public:
|
||||||
|
BroadCastSocketThread();
|
||||||
|
virtual void execute();
|
||||||
|
void signalQuit();
|
||||||
|
bool getQuitStatus();
|
||||||
|
bool getRunningStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
@@ -99,9 +128,18 @@ public:
|
|||||||
|
|
||||||
class ServerSocket: public Socket{
|
class ServerSocket: public Socket{
|
||||||
public:
|
public:
|
||||||
|
ServerSocket();
|
||||||
|
virtual ~ServerSocket();
|
||||||
void bind(int port);
|
void bind(int port);
|
||||||
void listen(int connectionQueueSize= SOMAXCONN);
|
void listen(int connectionQueueSize= SOMAXCONN);
|
||||||
Socket *accept();
|
Socket *accept();
|
||||||
|
void stopBroadCastThread();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
BroadCastSocketThread *broadCastThread;
|
||||||
|
void startBroadCastThread();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
@@ -108,6 +108,7 @@ public:
|
|||||||
// Misc
|
// Misc
|
||||||
// =====================================================
|
// =====================================================
|
||||||
int MessageBox(int handle, const char *msg, const char *title, int buttons);
|
int MessageBox(int handle, const char *msg, const char *title, int buttons);
|
||||||
|
void Tokenize(const string& str,vector<string>& tokens,const string& delimiters = " ");
|
||||||
bool isdir(const char *path);
|
bool isdir(const char *path);
|
||||||
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
|
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
|
||||||
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
|
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
// This file is part of Glest Shared Library (www.glest.org)
|
// This file is part of Glest Shared Library (www.glest.org)
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
// Copyright (C) 2001-2008 Martio Figueroa
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
// Misc
|
// Misc
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
void Tokenize(const string& str,vector<string>& tokens,const string& delimiters = " ");
|
||||||
bool isdir(const char *path);
|
bool isdir(const char *path);
|
||||||
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
|
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false);
|
||||||
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
|
void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
|
||||||
|
@@ -103,10 +103,15 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class ServerSocket: public Socket{
|
class ServerSocket: public Socket{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void bind(int port);
|
void bind(int port);
|
||||||
void listen(int connectionQueueSize= SOMAXCONN);
|
void listen(int connectionQueueSize= SOMAXCONN);
|
||||||
Socket *accept();
|
Socket *accept();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void broadcast_thread();
|
||||||
};
|
};
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
@@ -21,14 +21,19 @@
|
|||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
#include "conversion.h"
|
#include "conversion.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "platform_util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Shared::Util;
|
using namespace Shared::Util;
|
||||||
|
|
||||||
namespace Shared{ namespace Platform{
|
namespace Shared{ namespace Platform{
|
||||||
|
|
||||||
|
int Socket::broadcast_portno = 61357;
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Ip
|
// class Ip
|
||||||
// =====================================================
|
// =====================================================
|
||||||
@@ -68,6 +73,50 @@ string Ip::getString() const{
|
|||||||
// class Socket
|
// class Socket
|
||||||
// ===============================================
|
// ===============================================
|
||||||
|
|
||||||
|
std::vector<std::string> Socket::getLocalIPAddressList() {
|
||||||
|
std::vector<std::string> ipList;
|
||||||
|
|
||||||
|
/* get my host name */
|
||||||
|
char myhostname[101]="";
|
||||||
|
gethostname(myhostname,100);
|
||||||
|
|
||||||
|
struct hostent* myhostent = gethostbyname(myhostname);
|
||||||
|
|
||||||
|
// get all host IP addresses (Except for loopback)
|
||||||
|
char myhostaddr[101] = "";
|
||||||
|
int ipIdx = 0;
|
||||||
|
while (myhostent->h_addr_list[ipIdx] != 0) {
|
||||||
|
sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx]));
|
||||||
|
printf("%s\n",myhostaddr);
|
||||||
|
|
||||||
|
if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) {
|
||||||
|
ipList.push_back(myhostaddr);
|
||||||
|
}
|
||||||
|
ipIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check all linux network devices
|
||||||
|
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
/* I want to get an IPv4 IP address */
|
||||||
|
struct ifreq ifr;
|
||||||
|
ifr.ifr_addr.sa_family = AF_INET;
|
||||||
|
|
||||||
|
/* I want IP address attached to "eth0" */
|
||||||
|
strncpy(ifr.ifr_name, "eth1", IFNAMSIZ-1);
|
||||||
|
ioctl(fd, SIOCGIFADDR, &ifr);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
sprintf(myhostaddr, "%s",inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
|
||||||
|
printf("%s\n",myhostaddr);
|
||||||
|
|
||||||
|
if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) {
|
||||||
|
ipList.push_back(myhostaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipList;
|
||||||
|
}
|
||||||
|
|
||||||
Socket::Socket(int sock){
|
Socket::Socket(int sock){
|
||||||
this->sock= sock;
|
this->sock= sock;
|
||||||
}
|
}
|
||||||
@@ -644,10 +693,132 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function : discovery_response_thread
|
||||||
|
// in : none
|
||||||
|
// return : none
|
||||||
|
// Description: To be forked in its own thread to listen and respond to broadcasts from
|
||||||
|
// other servers
|
||||||
|
//
|
||||||
|
std::vector<string> ClientSocket::discoverServers() {
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
std::vector<string> foundServers;
|
||||||
|
|
||||||
|
short port; // The port for the broadcast.
|
||||||
|
struct sockaddr_in bcSender; // local socket address for the broadcast.
|
||||||
|
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
||||||
|
int bcfd; // The file descriptor used for the broadcast.
|
||||||
|
bool one = true; // Parameter for "setscokopt".
|
||||||
|
char buff[10024]; // Buffers the data to be broadcasted.
|
||||||
|
socklen_t alen;
|
||||||
|
int nb; // The number of bytes read.
|
||||||
|
|
||||||
|
port = htons( Socket::getBroadCastPort() );
|
||||||
|
|
||||||
|
// Prepare to receive the broadcast.
|
||||||
|
bcfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if( bcfd <= 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Create the address we are receiving on.
|
||||||
|
memset( (char*)&bcaddr, 0, sizeof(bcaddr));
|
||||||
|
bcaddr.sin_family = AF_INET;
|
||||||
|
bcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
bcaddr.sin_port = port;
|
||||||
|
|
||||||
|
int val = 1;
|
||||||
|
setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||||
|
|
||||||
|
if(bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %d\n", errno);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
// Keep getting packets forever.
|
||||||
|
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 3; )
|
||||||
|
{
|
||||||
|
alen = sizeof(struct sockaddr);
|
||||||
|
if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 )
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,inet_ntoa(bcSender.sin_addr) );
|
||||||
|
|
||||||
|
vector<string> tokens;
|
||||||
|
Tokenize(buff,tokens,":");
|
||||||
|
foundServers.push_back(tokens[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
return foundServers;
|
||||||
|
}
|
||||||
|
|
||||||
// ===============================================
|
// ===============================================
|
||||||
// class ServerSocket
|
// class ServerSocket
|
||||||
// ===============================================
|
// ===============================================
|
||||||
|
|
||||||
|
ServerSocket::ServerSocket() : Socket() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
broadCastThread = NULL;
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSocket::~ServerSocket() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
stopBroadCastThread();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::stopBroadCastThread() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
if(broadCastThread != NULL) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
broadCastThread->signalQuit();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; ) {
|
||||||
|
if(broadCastThread->getRunningStatus() == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(100);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
delete broadCastThread;
|
||||||
|
broadCastThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::startBroadCastThread() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
stopBroadCastThread();
|
||||||
|
|
||||||
|
broadCastThread = new BroadCastSocketThread();
|
||||||
|
broadCastThread->start();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
void ServerSocket::bind(int port)
|
void ServerSocket::bind(int port)
|
||||||
{
|
{
|
||||||
//sockaddr structure
|
//sockaddr structure
|
||||||
@@ -677,6 +848,10 @@ void ServerSocket::listen(int connectionQueueSize)
|
|||||||
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
||||||
throwException(szBuf);
|
throwException(szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
broadCastThread = new BroadCastSocketThread();
|
||||||
|
broadCastThread->start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket *ServerSocket::accept()
|
Socket *ServerSocket::accept()
|
||||||
@@ -698,5 +873,214 @@ Socket *ServerSocket::accept()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BroadCastSocketThread::BroadCastSocketThread() {
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
setQuitStatus(false);
|
||||||
|
setRunningStatus(false);
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BroadCastSocketThread::signalQuit() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
setQuitStatus(true);
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BroadCastSocketThread::setQuitStatus(bool value) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
mutexQuit.p();
|
||||||
|
quit = value;
|
||||||
|
mutexQuit.v();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BroadCastSocketThread::getQuitStatus() {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
bool retval = false;
|
||||||
|
mutexQuit.p();
|
||||||
|
retval = quit;
|
||||||
|
mutexQuit.v();
|
||||||
|
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BroadCastSocketThread::getRunningStatus() {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
bool retval = false;
|
||||||
|
mutexRunning.p();
|
||||||
|
retval = running;
|
||||||
|
mutexRunning.v();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,retval);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BroadCastSocketThread::setRunningStatus(bool value) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
|
||||||
|
|
||||||
|
mutexRunning.p();
|
||||||
|
running = value;
|
||||||
|
mutexRunning.v();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function : broadcast_thread
|
||||||
|
// in : none
|
||||||
|
// return : none
|
||||||
|
// Description: To be forked in its own thread to send out a broadcast to the local subnet
|
||||||
|
// the current broadcast message is <myhostname:my.ip.address.dotted>
|
||||||
|
//
|
||||||
|
void BroadCastSocketThread::execute() {
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
unsigned int tbcaddr; // The broadcast address.
|
||||||
|
short port; // The port for the broadcast.
|
||||||
|
struct sockaddr_in bcLocal; // local socket address for the broadcast.
|
||||||
|
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
||||||
|
int bcfd; // The socket used for the broadcast.
|
||||||
|
bool one = true; // Parameter for "setscokopt".
|
||||||
|
int pn; // The number of the packet broadcasted.
|
||||||
|
char buff[1024]; // Buffers the data to be broadcasted.
|
||||||
|
char myhostname[100]; // hostname of local machine
|
||||||
|
//char subnetmask[100]; // Subnet mask to broadcast to
|
||||||
|
struct in_addr myaddr; // My host address in net format
|
||||||
|
struct hostent* myhostent;
|
||||||
|
char * ptr; // some transient vars
|
||||||
|
int len,i;
|
||||||
|
|
||||||
|
/* get my host name */
|
||||||
|
gethostname(myhostname,100);
|
||||||
|
myhostent = gethostbyname(myhostname);
|
||||||
|
|
||||||
|
// get only the first host IP address
|
||||||
|
std::vector<std::string> ipList = Socket::getLocalIPAddressList();
|
||||||
|
|
||||||
|
/*
|
||||||
|
strcpy(subnetmask, ipList[0].c_str());
|
||||||
|
ptr = &subnetmask[0];
|
||||||
|
len = strlen(ptr);
|
||||||
|
|
||||||
|
// substitute the address with class C subnet mask x.x.x.255
|
||||||
|
for(i=len;i>0;i--) {
|
||||||
|
if(ptr[i] == '.') {
|
||||||
|
strcpy(&ptr[i+1],"255");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Convert the broadcast address from dot notation to a broadcast address.
|
||||||
|
//if( (tbcaddr = inet_addr( subnetmask )) == INADDR_NONE )
|
||||||
|
//{
|
||||||
|
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Badly formatted BC address: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
port = htons( Socket::getBroadCastPort() );
|
||||||
|
|
||||||
|
// Create the broadcast socket
|
||||||
|
memset( &bcLocal, 0, sizeof( struct sockaddr_in));
|
||||||
|
bcLocal.sin_family = AF_INET;
|
||||||
|
bcLocal.sin_addr.s_addr = htonl( INADDR_BROADCAST );
|
||||||
|
bcLocal.sin_port = port; // We are letting the OS fill in the port number for the local machine.
|
||||||
|
bcfd = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
|
||||||
|
// If there is an error, report it and terminate.
|
||||||
|
if( bcfd <= 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket.: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
// Mark the socket for broadcast.
|
||||||
|
else if( setsockopt( bcfd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast.: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
// Bind the address to the broadcast socket.
|
||||||
|
else {
|
||||||
|
|
||||||
|
//int val = 1;
|
||||||
|
//setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||||
|
|
||||||
|
//if(::bind(bcfd, (struct sockaddr *) &bcLocal, sizeof(struct sockaddr_in)) < 0) {
|
||||||
|
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not bind address to BC socket.: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
// Record the broadcast address of the receiver.
|
||||||
|
bcaddr.sin_family = AF_INET;
|
||||||
|
bcaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);//tbcaddr;
|
||||||
|
bcaddr.sin_port = port;
|
||||||
|
|
||||||
|
setRunningStatus(true);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send this machine's host name and address in hostname:n.n.n.n format
|
||||||
|
sprintf(buff,"%s:%s",myhostname,ipList[0].c_str());
|
||||||
|
|
||||||
|
time_t elapsed = 0;
|
||||||
|
for( pn = 1; ; pn++ )
|
||||||
|
{
|
||||||
|
if(difftime(time(NULL),elapsed) >= 1) {
|
||||||
|
time_t elapsed = time(NULL);
|
||||||
|
// Broadcast the packet to the subnet
|
||||||
|
if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting to [%s] the message: [%s]\n",subnetmask,buff);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep( 100 ); // send out broadcast every 1 seconds
|
||||||
|
}
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
catch(const exception &ex) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
|
setRunningStatus(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
setRunningStatus(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setRunningStatus(false);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is exiting\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
||||||
|
@@ -126,6 +126,23 @@ int64 Chrono::getCurTicks() {
|
|||||||
// Misc
|
// Misc
|
||||||
// =====================================
|
// =====================================
|
||||||
|
|
||||||
|
void Tokenize(const string& str,vector<string>& tokens,const string& delimiters) {
|
||||||
|
// Skip delimiters at beginning.
|
||||||
|
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||||||
|
// Find first "non-delimiter".
|
||||||
|
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||||||
|
|
||||||
|
while (string::npos != pos || string::npos != lastPos) {
|
||||||
|
// Found a token, add it to the vector.
|
||||||
|
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||||
|
// Skip delimiters. Note the "not_of"
|
||||||
|
lastPos = str.find_first_not_of(delimiters, pos);
|
||||||
|
// Find next "non-delimiter"
|
||||||
|
pos = str.find_first_of(delimiters, lastPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This was the simplest, most portable solution i could find in 5 mins for linux
|
// This was the simplest, most portable solution i could find in 5 mins for linux
|
||||||
int MessageBox(int handle, const char *msg, const char *title, int buttons) {
|
int MessageBox(int handle, const char *msg, const char *title, int buttons) {
|
||||||
char cmd[1024]="";
|
char cmd[1024]="";
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
// This file is part of Glest Shared Library (www.glest.org)
|
// This file is part of Glest Shared Library (www.glest.org)
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
// Copyright (C) 2001-2008 Martio Figueroa
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
@@ -186,6 +186,23 @@ void PlatformExceptionHandler::install(string dumpFileName){
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
// class Misc
|
// class Misc
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
|
void Tokenize(const string& str,vector<string>& tokens,const string& delimiters) {
|
||||||
|
// Skip delimiters at beginning.
|
||||||
|
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||||||
|
// Find first "non-delimiter".
|
||||||
|
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||||||
|
|
||||||
|
while (string::npos != pos || string::npos != lastPos) {
|
||||||
|
// Found a token, add it to the vector.
|
||||||
|
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||||
|
// Skip delimiters. Note the "not_of"
|
||||||
|
lastPos = str.find_first_not_of(delimiters, pos);
|
||||||
|
// Find next "non-delimiter"
|
||||||
|
pos = str.find_first_of(delimiters, lastPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound) {
|
void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound) {
|
||||||
results.clear();
|
results.clear();
|
||||||
int pathCount = paths.size();
|
int pathCount = paths.size();
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
// This file is part of Glest Shared Library (www.glest.org)
|
// This file is part of Glest Shared Library (www.glest.org)
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
// Copyright (C) 2001-2008 Martio Figueroa
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
@@ -41,9 +42,19 @@ void SystemFlags::OutputDebug(DebugType type, const char *fmt, ...) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the current time. */
|
||||||
|
time_t curtime = time (NULL);
|
||||||
|
/* Convert it to local time representation. */
|
||||||
|
struct tm *loctime = localtime (&curtime);
|
||||||
|
char szBuf2[100]="";
|
||||||
|
strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime);
|
||||||
|
|
||||||
va_list argList;
|
va_list argList;
|
||||||
va_start(argList, fmt);
|
va_start(argList, fmt);
|
||||||
|
|
||||||
|
char szBuf[1024]="";
|
||||||
|
vsprintf(szBuf,fmt, argList);
|
||||||
|
|
||||||
// Either output to a logfile or
|
// Either output to a logfile or
|
||||||
if(SystemFlags::debugLogFile != NULL && SystemFlags::debugLogFile[0] != 0) {
|
if(SystemFlags::debugLogFile != NULL && SystemFlags::debugLogFile[0] != 0) {
|
||||||
if(fileStream.is_open() == false) {
|
if(fileStream.is_open() == false) {
|
||||||
@@ -53,16 +64,13 @@ void SystemFlags::OutputDebug(DebugType type, const char *fmt, ...) {
|
|||||||
|
|
||||||
//printf("Logfile is open [%s]\n",SystemFlags::debugLogFile);
|
//printf("Logfile is open [%s]\n",SystemFlags::debugLogFile);
|
||||||
|
|
||||||
char szBuf[1024]="";
|
|
||||||
vsprintf(szBuf,fmt, argList);
|
|
||||||
|
|
||||||
//printf("writing to logfile [%s]\n",szBuf);
|
//printf("writing to logfile [%s]\n",szBuf);
|
||||||
fileStream << szBuf;
|
fileStream << "[" << szBuf2 << "] " << szBuf;
|
||||||
fileStream.flush();
|
fileStream.flush();
|
||||||
}
|
}
|
||||||
// output to console
|
// output to console
|
||||||
else {
|
else {
|
||||||
vprintf(fmt, argList);
|
printf("[%s] %s", szBuf2, szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(argList);
|
va_end(argList);
|
||||||
|
Reference in New Issue
Block a user