Cosmetic changes mostly, removed unused functions.

This commit is contained in:
hiker 2015-10-20 22:42:57 +11:00
parent 6fc4b9c19d
commit 0dfa05227e
3 changed files with 261 additions and 267 deletions

View File

@ -54,89 +54,154 @@ const char* inet_ntop(int af, const void* src, char* dst, int cnt)
} }
#endif #endif
Synchronised<FILE*> STKHost::m_log_file = NULL;
FILE* STKHost::m_log_file = NULL; // ============================================================================
pthread_mutex_t STKHost::m_log_mutex; /** Constructor that just initialises this object (esp. opening the packet
* log file), but it does not start a listener thread.
void STKHost::logPacket(const NetworkString &ns, bool incoming) */
STKHost::STKHost()
{ {
if (m_log_file == NULL) m_host = NULL;
return; m_listening_thread = NULL;
pthread_mutex_lock(&m_log_mutex); m_log_file.setAtomic(NULL);
if (incoming) pthread_mutex_init(&m_exit_mutex, NULL);
fprintf(m_log_file, "[%d\t] <-- ", (int)(StkTime::getRealTime())); if (UserConfigParams::m_packets_log_filename.toString() != "")
else
fprintf(m_log_file, "[%d\t] --> ", (int)(StkTime::getRealTime()));
for (int i = 0; i < ns.size(); i++)
{ {
fprintf(m_log_file, "%d.", ns[i]); std::string s = file_manager
} ->getUserConfigFile(UserConfigParams::m_packets_log_filename);
fprintf(m_log_file, "\n"); m_log_file.setAtomic(fopen(s.c_str(), "w+"));
pthread_mutex_unlock(&m_log_mutex);
} }
if (!m_log_file.getData())
Log::warn("STKHost", "Network packets won't be logged: no file.");
} // STKHost
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Destructor. Stops the listening thread, closes the packet log file and
* destroys the enet host.
*/
STKHost::~STKHost()
{
stopListening();
if (m_log_file.getData())
{
m_log_file.lock();
fclose(m_log_file.getData());
Log::warn("STKHost", "Packet logging file has been closed.");
m_log_file.getData() = NULL;
m_log_file.unlock();
}
if (m_host)
{
enet_host_destroy(m_host);
}
} // ~STKHost
void* STKHost::receive_data(void* self) // ----------------------------------------------------------------------------
/** \brief Log packets into a file
* \param ns : The data in the packet
* \param incoming : True if the packet comes from a peer.
* False if it's sent to a peer.
*/
void STKHost::logPacket(const NetworkString &ns, bool incoming)
{
if (m_log_file.getData() == NULL) // read only access, no need to lock
return;
char *arrow = incoming ? "<--" : "-->";
m_log_file.lock();
fprintf(m_log_file.getData(), "[%d\t] %s ",
(int)(StkTime::getRealTime()), arrow);
for (int i = 0; i < ns.size(); i++)
{
fprintf(m_log_file.getData(), "%d.", ns[i]);
}
fprintf(m_log_file.getData(), "\n");
m_log_file.unlock();
} // logPacket
// ----------------------------------------------------------------------------
/** \brief Starts the listening of events from ENet.
* Starts a thread for receiveData that updates it as often as possible.
*/
void STKHost::startListening()
{
pthread_mutex_lock(&m_exit_mutex); // will let the update function start
m_listening_thread = new pthread_t;
pthread_create(m_listening_thread, NULL, &STKHost::mainLoop, this);
} // startListening
// ----------------------------------------------------------------------------
/** \brief Stops the listening of events from ENet.
* Stops the thread that was receiving events.
*/
void STKHost::stopListening()
{
if (m_listening_thread)
{
// This will stop the update function on its next update
pthread_mutex_unlock(&m_exit_mutex);
pthread_join(*m_listening_thread, NULL); // wait for the thread to end
}
} // stopListening
// ---------------------------------------------------------------------------
/** \brief Returns true when the thread should stop listening.
*/
int STKHost::mustStopListening()
{
switch (pthread_mutex_trylock(&m_exit_mutex)) {
case 0: /* if we got the lock, unlock and return 1 (true) */
pthread_mutex_unlock(&m_exit_mutex);
return 1;
case EBUSY: /* return 0 (false) if the mutex was locked */
return 0;
}
return 1;
} // mustStopListening
// ----------------------------------------------------------------------------
/** \brief Thread function checking if data is received.
* This function tries to get data from network low-level functions as
* often as possible. When something is received, it generates an
* event and passes it to the Network Manager.
* \param self : used to pass the ENet host to the function.
*/
void* STKHost::mainLoop(void* self)
{ {
ENetEvent event; ENetEvent event;
STKHost* myself = (STKHost*)(self); STKHost* myself = (STKHost*)(self);
ENetHost* host = myself->m_host; ENetHost* host = myself->m_host;
while (!myself->mustStopListening()) while (!myself->mustStopListening())
{ {
while (enet_host_service(host, &event, 20) != 0) { while (enet_host_service(host, &event, 20) != 0)
Event* evt = new Event(&event); {
if (evt->type == EVENT_TYPE_MESSAGE) Event* stk_event = new Event(&event);
logPacket(evt->data(), true); if (stk_event->type == EVENT_TYPE_MESSAGE)
logPacket(stk_event->data(), true);
if (event.type != ENET_EVENT_TYPE_NONE) if (event.type != ENET_EVENT_TYPE_NONE)
NetworkManager::getInstance()->notifyEvent(evt); NetworkManager::getInstance()->notifyEvent(stk_event);
delete evt; delete stk_event;
} } // while enet_host_service
} } // while !mustStopListening
myself->m_listening = false;
free(myself->m_listening_thread); free(myself->m_listening_thread);
myself->m_listening_thread = NULL; myself->m_listening_thread = NULL;
Log::info("STKHost", "Listening has been stopped"); Log::info("STKHost", "Listening has been stopped");
return NULL; return NULL;
} } // mainLoop
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Setups this host as a server.
STKHost::STKHost() * \param address : The IPv4 address of incoming connections.
{ * \param port : The port on which the server listens.
m_host = NULL; * \param peer_count : The maximum number of peers.
m_listening_thread = NULL; * \param channel_limit : The maximum number of channels per peer.
m_log_file = NULL; * \param max_incoming_bandwidth : The maximum incoming bandwidth.
pthread_mutex_init(&m_exit_mutex, NULL); * \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
pthread_mutex_init(&m_log_mutex, NULL); */
if (UserConfigParams::m_packets_log_filename.toString() != "")
{
std::string s =
file_manager->getUserConfigFile(UserConfigParams::m_packets_log_filename);
m_log_file = fopen(s.c_str(), "w+");
}
if (!m_log_file)
Log::warn("STKHost", "Network packets won't be logged: no file.");
}
// ----------------------------------------------------------------------------
STKHost::~STKHost()
{
stopListening();
if (m_log_file)
{
fclose(m_log_file);
Log::warn("STKHost", "Packet logging file has been closed.");
}
if (m_host)
{
enet_host_destroy(m_host);
}
}
// ----------------------------------------------------------------------------
void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count, void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
int channel_limit, uint32_t max_incoming_bandwidth, int channel_limit, uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth) uint32_t max_outgoing_bandwidth)
@ -154,15 +219,21 @@ void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
m_host = enet_host_create(addr, peer_count, channel_limit, m_host = enet_host_create(addr, peer_count, channel_limit,
max_incoming_bandwidth, max_outgoing_bandwidth); max_incoming_bandwidth, max_outgoing_bandwidth);
if (m_host == NULL) if (!m_host)
{ {
Log::error("STKHost", "An error occurred while trying to create an ENet" Log::fatal("STKHost", "An error occurred while trying to create an ENet"
" server host."); " server host.");
exit (EXIT_FAILURE);
}
} }
} // setupServer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Setups the host as a client.
* In fact there is only one peer connected to this host.
* \param peer_count : The maximum number of peers.
* \param channel_limit : The maximum number of channels per peer.
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
*/
void STKHost::setupClient(int peer_count, int channel_limit, void STKHost::setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth, uint32_t max_incoming_bandwidth,
@ -170,38 +241,22 @@ void STKHost::setupClient(int peer_count, int channel_limit,
{ {
m_host = enet_host_create(NULL, peer_count, channel_limit, m_host = enet_host_create(NULL, peer_count, channel_limit,
max_incoming_bandwidth, max_outgoing_bandwidth); max_incoming_bandwidth, max_outgoing_bandwidth);
if (m_host == NULL) if (!m_host)
{ {
Log::error("STKHost", "An error occurred while trying to create an ENet" Log::fatal ("STKHost", "An error occurred while trying to create an "
" client host."); "ENet client host.");
exit (EXIT_FAILURE);
}
} }
} // setupClient
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Sends a packet whithout ENet adding its headers.
void STKHost::startListening() * This function is used in particular to achieve the STUN protocol.
{ * \param data : Data to send.
pthread_mutex_lock(&m_exit_mutex); // will let the update function start * \param length : Length of the sent data.
m_listening_thread = (pthread_t*)(malloc(sizeof(pthread_t))); * \param dst : Destination of the packet.
pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this); */
m_listening = true; void STKHost::sendRawPacket(uint8_t* data, int length,
} const TransportAddress& dst)
// ----------------------------------------------------------------------------
void STKHost::stopListening()
{
if(m_listening_thread)
{
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function on its next update
pthread_join(*m_listening_thread, NULL); // wait the thread to end
}
}
// ----------------------------------------------------------------------------
void STKHost::sendRawPacket(uint8_t* data, int length, const TransportAddress& dst)
{ {
struct sockaddr_in to; struct sockaddr_in to;
int to_len = sizeof(to); int to_len = sizeof(to);
@ -215,54 +270,43 @@ void STKHost::sendRawPacket(uint8_t* data, int length, const TransportAddress& d
Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str()); Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str());
STKHost::logPacket(NetworkString(std::string((char*)(data), length)), STKHost::logPacket(NetworkString(std::string((char*)(data), length)),
false); false);
} } // sendRawPacket
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Receives a packet directly from the network interface.
uint8_t* STKHost::receiveRawPacket() * Receive a packet whithout ENet processing it and returns the
{ * sender's ip address and port in the TransportAddress structure.
uint8_t* buffer; // max size needed normally (only used for stun) * \param sender : Stores the transport address of the sender of the
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); * received packet.
memset(buffer, 0, 2048); * \return A string containing the data of the received packet.
*/
int len = recv(m_host->socket,(char*)buffer,2048, 0);
int i = 0;
// wait to receive the message because enet sockets are non-blocking
while(len < 0)
{
i++;
len = recv(m_host->socket,(char*)buffer,2048, 0);
StkTime::sleep(1);
}
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
return buffer;
}
// ----------------------------------------------------------------------------
uint8_t* STKHost::receiveRawPacket(TransportAddress* sender) uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
{ {
uint8_t* buffer; // max size needed normally (only used for stun) const int LEN = 2048;
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); // max size needed normally (only used for stun)
memset(buffer, 0, 2048); uint8_t* buffer = new uint8_t[LEN];
memset(buffer, 0, LEN);
socklen_t from_len; socklen_t from_len;
struct sockaddr_in addr; struct sockaddr_in addr;
from_len = sizeof(addr); from_len = sizeof(addr);
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len); int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
(struct sockaddr*)(&addr), &from_len );
int i = 0; int i = 0;
// wait to receive the message because enet sockets are non-blocking // wait to receive the message because enet sockets are non-blocking
while(len == -1) // nothing received while(len == -1) // nothing received
{ {
i++;
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len);
StkTime::sleep(1); // wait 1 millisecond between two checks StkTime::sleep(1); // wait 1 millisecond between two checks
i++;
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
(struct sockaddr*)(&addr), &from_len );
} }
if (len == SOCKET_ERROR) if (len == SOCKET_ERROR)
{ {
Log::error("STKHost", "Problem with the socket. Please contact the dev team."); Log::error("STKHost",
"Problem with the socket. Please contact the dev team.");
} }
// we received the data // we received the data
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) ); sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
@ -270,69 +314,89 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
if (addr.sin_family == AF_INET) if (addr.sin_family == AF_INET)
{ {
Log::info("STKHost", "IPv4 Address of the sender was %s", sender->toString().c_str()); Log::info("STKHost", "IPv4 Address of the sender was %s",
sender->toString().c_str());
} }
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true); STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
return buffer; return buffer;
} } // receiveRawPacket(TransportAddress* sender)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Receives a packet directly from the network interface and
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender, int max_tries) * filter its address.
* Receive a packet whithout ENet processing it. Checks that the
* sender of the packet is the one that corresponds to the sender
* parameter. Does not check the port right now.
* \param sender : Transport address of the original sender of the
* wanted packet.
* \param max_tries : Number of times we try to read data from the
* socket. This is aproximately the time we wait in
* milliseconds. -1 means eternal tries.
* \return A string containing the data of the received packet
* matching the sender's ip address.
*/
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender,
int max_tries)
{ {
uint8_t* buffer; // max size needed normally (only used for stun) const int LEN = 2048;
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); uint8_t* buffer = new uint8_t[LEN];
memset(buffer, 0, 2048); memset(buffer, 0, LEN);
socklen_t from_len; socklen_t from_len;
struct sockaddr_in addr; struct sockaddr_in addr;
from_len = sizeof(addr); from_len = sizeof(addr);
int len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len); int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
(struct sockaddr*)(&addr), &from_len );
int i = 0; int count = 0;
// wait to receive the message because enet sockets are non-blocking // wait to receive the message because enet sockets are non-blocking
while(len < 0 || addr.sin_addr.s_addr == sender.getIP()) while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
{ {
i++; count++;
if (len>=0) if (len>=0)
{ {
Log::info("STKHost", "Message received but the ip address didn't match the expected one."); Log::info("STKHost", "Message received but the ip address didn't "
"match the expected one.");
} }
len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, (struct sockaddr*)(&addr), &from_len); len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
(struct sockaddr*)(&addr), &from_len);
StkTime::sleep(1); // wait 1 millisecond between two checks StkTime::sleep(1); // wait 1 millisecond between two checks
if (i >= max_tries && max_tries != -1) if (count >= max_tries && max_tries != -1)
{ {
Log::verbose("STKHost", "No answer from the server on %u.%u.%u.%u:%u", (m_host->address.host&0xff), TransportAddress a(m_host->address);
(m_host->address.host>>8&0xff), Log::verbose("STKHost", "No answer from the server on %s",
(m_host->address.host>>16&0xff), a.toString().c_str());
(m_host->address.host>>24&0xff),
(m_host->address.port));
return NULL; return NULL;
} }
} }
if (addr.sin_family == AF_INET) if (addr.sin_family == AF_INET)
{ {
char s[20]; TransportAddress a(addr.sin_addr.s_addr);
inet_ntop(AF_INET, &(addr.sin_addr), s, 20); Log::info("STKHost", "IPv4 Address of the sender was %s",
Log::info("STKHost", "IPv4 Address of the sender was %s", s); a.toString(false).c_str());
} }
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true); STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
return buffer; return buffer;
} } // receiveRawPacket(const TransportAddress& sender, int max_tries)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Broadcasts a packet to all peers.
* \param data : Data to send.
*/
void STKHost::broadcastPacket(const NetworkString& data, bool reliable) void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
{ {
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1, ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
(reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNSEQUENCED)); reliable ? ENET_PACKET_FLAG_RELIABLE
: ENET_PACKET_FLAG_UNSEQUENCED);
enet_host_broadcast(m_host, 0, packet); enet_host_broadcast(m_host, 0, packet);
STKHost::logPacket(data, false); STKHost::logPacket(data, false);
} } // broadcastPacket
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Tells if a peer is known.
* \return True if the peer is known, false elseway.
*/
bool STKHost::peerExists(const TransportAddress& peer) bool STKHost::peerExists(const TransportAddress& peer)
{ {
for (unsigned int i = 0; i < m_host->peerCount; i++) for (unsigned int i = 0; i < m_host->peerCount; i++)
@ -344,10 +408,12 @@ bool STKHost::peerExists(const TransportAddress& peer)
} }
} }
return false; return false;
} } // peerExists
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** \brief Tells if a peer is known and connected.
* \return True if the peer is known and connected, false elseway.
*/
bool STKHost::isConnectedTo(const TransportAddress& peer) bool STKHost::isConnectedTo(const TransportAddress& peer)
{ {
for (unsigned int i = 0; i < m_host->peerCount; i++) for (unsigned int i = 0; i < m_host->peerCount; i++)
@ -359,22 +425,9 @@ bool STKHost::isConnectedTo(const TransportAddress& peer)
} }
} }
return false; return false;
} } // isConnectedTo
// ---------------------------------------------------------------------------
int STKHost::mustStopListening()
{
switch(pthread_mutex_trylock(&m_exit_mutex)) {
case 0: /* if we got the lock, unlock and return 1 (true) */
pthread_mutex_unlock(&m_exit_mutex);
return 1;
case EBUSY: /* return 0 (false) if the mutex was locked */
return 0;
}
return 1;
}
// ----------------------------------------------------------------------------
uint16_t STKHost::getPort() const uint16_t STKHost::getPort() const
{ {
struct sockaddr_in sin; struct sockaddr_in sin;

View File

@ -22,9 +22,9 @@
#ifndef STK_HOST_HPP #ifndef STK_HOST_HPP
#define STK_HOST_HPP #define STK_HOST_HPP
#include "network/types.hpp"
#include "network/network_string.hpp" #include "network/network_string.hpp"
#include "network/types.hpp"
#include "utils/synchronised.hpp"
// enet.h includes win32.h, which without lean_and_mean includes // enet.h includes win32.h, which without lean_and_mean includes
// winspool.h, which defines MAX_PRIORITY as a macro, which then // winspool.h, which defines MAX_PRIORITY as a macro, which then
@ -47,6 +47,20 @@
class STKHost class STKHost
{ {
friend class STKPeer; // allow direct enet modifications in implementations friend class STKPeer; // allow direct enet modifications in implementations
private:
/** ENet host interfacing sockets. */
ENetHost* m_host;
/** Id of thread listening to enet events. */
pthread_t* m_listening_thread;
/** Mutex used to stop this thread. */
pthread_mutex_t m_exit_mutex;
//** Where to log packets. If NULL for FILE* logging is disabled. */
static Synchronised<FILE*> m_log_file;
public: public:
/*! \enum HOST_TYPE /*! \enum HOST_TYPE
* \brief Defines three host types for the server. * \brief Defines three host types for the server.
@ -64,109 +78,31 @@ class STKHost
/*! \brief Destructor */ /*! \brief Destructor */
virtual ~STKHost(); virtual ~STKHost();
/*! \brief Log packets into a file
* \param ns : The data in the packet
* \param incoming : True if the packet comes from a peer.
* False if it's sent to a peer.
*/
static void logPacket(const NetworkString &ns, bool incoming); static void logPacket(const NetworkString &ns, bool incoming);
static void* mainLoop(void* self);
/*! \brief Thread function checking if data is received.
* This function tries to get data from network low-level functions as
* often as possible. When something is received, it generates an
* event and passes it to the Network Manager.
* \param self : used to pass the ENet host to the function.
*/
static void* receive_data(void* self);
/*! \brief Setups the host as a server.
* \param address : The IPv4 address of incoming connections.
* \param port : The port on which the server listens.
* \param peer_count : The maximum number of peers.
* \param channel_limit : The maximum number of channels per peer.
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
*/
void setupServer(uint32_t address, uint16_t port, void setupServer(uint32_t address, uint16_t port,
int peer_count, int channel_limit, int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth, uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth); uint32_t max_outgoing_bandwidth);
/*! \brief Setups the host as a client.
* In fact there is only one peer connected to this host.
* \param peer_count : The maximum number of peers.
* \param channel_limit : The maximum number of channels per peer.
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
*/
void setupClient(int peer_count, int channel_limit, void setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth, uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth); uint32_t max_outgoing_bandwidth);
/*! \brief Starts the listening of events from ENet.
* Starts a thread that updates it as often as possible.
*/
void startListening(); void startListening();
/*! \brief Stops the listening of events from ENet.
* Stops the thread that was receiving events.
*/
void stopListening(); void stopListening();
/*! \brief Sends a packet whithout ENet adding its headers.
* This function is used in particular to achieve the STUN protocol.
* \param data : Data to send.
* \param length : Length of the sent data.
* \param dst : Destination of the packet.
*/
void sendRawPacket(uint8_t* data, int length, void sendRawPacket(uint8_t* data, int length,
const TransportAddress& dst); const TransportAddress& dst);
/*! \brief Receives a packet directly from the network interface.
* Receive a packet whithout ENet processing it.
* \return A string containing the data of the received packet.
*/
uint8_t* receiveRawPacket();
uint8_t* receiveRawPacket(TransportAddress* sender); uint8_t* receiveRawPacket(TransportAddress* sender);
/*! \brief Receives a packet directly from the network interface and uint8_t* receiveRawPacket(const TransportAddress& sender,
* filter its address. int max_tries = -1);
* Receive a packet whithout ENet processing it. Checks that the void broadcastPacket(const NetworkString& data,
* sender of the packet is the one that corresponds to the sender bool reliable = true);
* parameter. Does not check the port right now.
* \param sender : Transport address of the original sender of the
* wanted packet.
* \param max_tries : Number of times we try to read data from the
* socket. This is aproximately the time we wait in milliseconds.
* -1 means eternal tries.
* \return A string containing the data of the received packet
* matching the sender's ip address.
*/
uint8_t* receiveRawPacket(const TransportAddress& sender, int max_tries = -1);
/*! \brief Broadcasts a packet to all peers.
* \param data : Data to send.
*/
void broadcastPacket(const NetworkString& data, bool reliable = true);
/*! \brief Tells if a peer is known.
* \return True if the peer is known, false elseway.
*/
bool peerExists(const TransportAddress& peer_address); bool peerExists(const TransportAddress& peer_address);
/*! \brief Tells if a peer is known and connected.
* \return True if the peer is known and connected, false elseway.
*/
bool isConnectedTo(const TransportAddress& peer_address); bool isConnectedTo(const TransportAddress& peer_address);
/*! \brief Returns true when the thread should stop listening. */
int mustStopListening(); int mustStopListening();
/*! \brief Returns true when the thread has stopped listening. */
bool hasStoppedListening() const { return m_listening; }
uint32_t getAddress() const { return m_host->address.host; }
uint16_t getPort() const; uint16_t getPort() const;
protected: // --------------------------------------------------------------------
ENetHost* m_host; //!< ENet host interfacing sockets. uint32_t getAddress() const { return m_host->address.host; }
pthread_t* m_listening_thread; //!< Thread listening network events.
pthread_mutex_t m_exit_mutex; //!< Mutex to kill properly the thread
bool m_listening;
static FILE* m_log_file; //!< Where to log packets
static pthread_mutex_t m_log_mutex; //!< To write in the log only once at a time
}; };

View File

@ -149,14 +149,19 @@ public:
} // operator!= } // operator!=
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a std::string representing the ip address and port in human /** Returns a std::string representing the ip address and port in human
* readable format. */ * readable format.
std::string toString() const * \param show_port True if the port should be shown as well, otherwise
* only the ip address will be returned.
*/
std::string toString(bool show_port = true) const
{ {
return std::string s =
StringUtils::insertValues("%d.%d.%d.%d:%d", StringUtils::insertValues("%d.%d.%d.%d",
((m_ip >> 24) & 0xff), ((m_ip >> 16) & 0xff), ((m_ip >> 24) & 0xff), ((m_ip >> 16) & 0xff),
((m_ip >> 8) & 0xff), ((m_ip >> 0) & 0xff), ((m_ip >> 8) & 0xff), ((m_ip >> 0) & 0xff));
m_port ); if (show_port)
s += StringUtils::insertValues(":%d", m_port);
return s;
} // toString } // toString
}; // TransportAddress }; // TransportAddress