summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2005-04-18 12:55:41 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2005-04-18 12:55:41 +0000
commit3370b59fe2c9544fddebb1281505ddec3d22c0e1 (patch)
tree1e5ffa36ccf1a45cb678781acce65231df0c656e
parent5478d27cb1affe4c7be40dab32058ada95258a1f (diff)
downloadmanaserv-3370b59fe2c9544fddebb1281505ddec3d22c0e1.tar.gz
manaserv-3370b59fe2c9544fddebb1281505ddec3d22c0e1.tar.bz2
manaserv-3370b59fe2c9544fddebb1281505ddec3d22c0e1.tar.xz
manaserv-3370b59fe2c9544fddebb1281505ddec3d22c0e1.zip
Server now succesfully listens for connections, accepts them, receives some
data in a crude way and cleans up connection on client disconnect.
-rw-r--r--src/connectionhandler.cpp107
-rw-r--r--src/connectionhandler.h12
-rw-r--r--src/netcomputer.cpp11
-rw-r--r--src/netcomputer.h13
-rw-r--r--src/netsession.cpp42
5 files changed, 151 insertions, 34 deletions
diff --git a/src/connectionhandler.cpp b/src/connectionhandler.cpp
index c843140c..953f5c15 100644
--- a/src/connectionhandler.cpp
+++ b/src/connectionhandler.cpp
@@ -22,11 +22,118 @@
*/
#include "connectionhandler.h"
+#include "netsession.h"
+
+#define MAX_CLIENTS 1024
ConnectionHandler::ConnectionHandler()
{
}
+void ConnectionHandler::startListen(ListenThreadData *ltd)
+{
+ // Allocate a socket set
+ SDLNet_SocketSet set = SDLNet_AllocSocketSet(MAX_CLIENTS);
+ if (!set) {
+ printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
+ exit(1);
+ }
+
+ // Add the server socket to the socket set
+ if (SDLNet_TCP_AddSocket(set, ltd->socket) < 0) {
+ printf("SDLNet_AddSocket: %s\n", SDLNet_GetError());
+ exit(1);
+ }
+
+ // Keep checking for socket activity while running
+ while (ltd->running)
+ {
+ int numready = SDLNet_CheckSockets(set, 100);
+
+ if (numready == -1)
+ {
+ printf("SDLNet_CheckSockets: %s\n", SDLNet_GetError());
+ // When this is a system error, perror may help us
+ perror("SDLNet_CheckSockets");
+ }
+ else if (numready > 0)
+ {
+ printf("%d sockets with activity!\n", numready);
+
+ // Check server socket
+ if (SDLNet_SocketReady(ltd->socket))
+ {
+ TCPsocket client = SDLNet_TCP_Accept(ltd->socket);
+ if (client)
+ {
+ // Add the client socket to the socket set
+ if (SDLNet_TCP_AddSocket(set, client) < 0) {
+ printf("SDLNet_AddSocket: %s\n", SDLNet_GetError());
+ }
+ else {
+ NetComputer *comp = new NetComputer(this);
+ clients[comp] = client;
+ computerConnected(comp);
+ printf("%d clients connected\n", clients.size());
+ }
+ }
+ }
+
+ // Check client sockets
+ std::map<NetComputer*, TCPsocket>::iterator i;
+ for (i = clients.begin(); i != clients.end(); )
+ {
+ NetComputer *comp = (*i).first;
+ TCPsocket s = (*i).second;
+
+ if (SDLNet_SocketReady(s))
+ {
+ char buffer[1024];
+ int result = SDLNet_TCP_Recv(s, buffer, 1024);
+ if (result <= 0)
+ {
+ SDLNet_TCP_DelSocket(set, s);
+ SDLNet_TCP_Close(s);
+ computerDisconnected(comp);
+ delete comp;
+ comp = NULL;
+ }
+ else
+ {
+ buffer[result] = 0;
+ printf("Received %s\n", buffer);
+ }
+ }
+
+ // Traverse to next client, possibly deleting current
+ if (comp == NULL) {
+ std::map<NetComputer*, TCPsocket>::iterator ii = i;
+ ii++;
+ clients.erase(i);
+ i = ii;
+ }
+ else {
+ i++;
+ }
+ }
+ }
+ }
+
+ // - Disconnect all clients (close sockets)
+
+ SDLNet_FreeSocketSet(set);
+}
+
+void ConnectionHandler::computerConnected(NetComputer *comp)
+{
+ printf("A client connected!\n");
+}
+
+void ConnectionHandler::computerDisconnected(NetComputer *comp)
+{
+ printf("A client disconnected!\n");
+}
+
void ConnectionHandler::registerHandler(
unsigned int msgId, MessageHandler *handler)
{
diff --git a/src/connectionhandler.h b/src/connectionhandler.h
index bc5f0965..ab01dc2c 100644
--- a/src/connectionhandler.h
+++ b/src/connectionhandler.h
@@ -28,6 +28,10 @@
#include "netcomputer.h"
#include "packet.h"
#include <map>
+#include <SDL_net.h>
+
+// Forward declaration
+class ListenThreadData;
/**
* This class represents the connection handler interface. The connection
@@ -43,6 +47,13 @@ class ConnectionHandler
ConnectionHandler();
/**
+ * Starts listening to the server socket. It accepts new connections
+ * and receives data from connected clients. All computers are
+ * disconnected when listening stops.
+ */
+ void startListen(ListenThreadData *ltd);
+
+ /**
* Called when a computer connects to a network session.
*/
void computerConnected(NetComputer *computer);
@@ -72,6 +83,7 @@ class ConnectionHandler
private:
std::map<unsigned int, MessageHandler*> handlers;
+ std::map<NetComputer*, TCPsocket> clients;
};
#endif
diff --git a/src/netcomputer.cpp b/src/netcomputer.cpp
index 89317dc0..79110fd4 100644
--- a/src/netcomputer.cpp
+++ b/src/netcomputer.cpp
@@ -23,3 +23,14 @@
#include "netcomputer.h"
+
+NetComputer::NetComputer(ConnectionHandler *handler):
+ handler(handler)
+{
+}
+
+void NetComputer::disconnect(const std::string &reason)
+{
+ // Somehow notify the netsession listener about the disconnect after
+ // sending this computer a disconnect message containing the reason.
+}
diff --git a/src/netcomputer.h b/src/netcomputer.h
index 02948207..1a73d675 100644
--- a/src/netcomputer.h
+++ b/src/netcomputer.h
@@ -25,10 +25,11 @@
#define _TMW_SERVER_NETCOMPUTER_
#include "packet.h"
+#include <SDL_net.h>
#include <string>
// Forward declaration
-class NetSession;
+class ConnectionHandler;
/**
* This class represents a known computer on the network. For example a
@@ -40,12 +41,7 @@ class NetComputer
/**
* Constructor.
*/
- NetComputer(NetSession *session);
-
- /**
- * Returns the netsession that the computer is attached to.
- */
- NetSession *getSession();
+ NetComputer(ConnectionHandler *handler);
/**
* Returns <code>true</code> if this computer is disconnected.
@@ -66,6 +62,9 @@ class NetComputer
*/
void send(Packet *p);
//void send(Packet *p, bool reliable = true);
+
+ private:
+ ConnectionHandler *handler;
};
#endif
diff --git a/src/netsession.cpp b/src/netsession.cpp
index a617c105..f4f77214 100644
--- a/src/netsession.cpp
+++ b/src/netsession.cpp
@@ -23,35 +23,16 @@
#include "netsession.h"
-#define MAX_CLIENTS 1024
-
+/**
+ * This function is the new thread created to listen to a server socket. It
+ * immediately passes control over to the connection handler instance that will
+ * deal with incoming connections and data.
+ */
int startListenThread(void *data)
{
ListenThreadData *ltd = (ListenThreadData*)data;
-
- // Allocate a socket set
- SDLNet_SocketSet set = SDLNet_AllocSocketSet(MAX_CLIENTS);
- if (!set) {
- printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
- exit(1);
- }
-
- // Add the server socket to the socket set
- if (SDLNet_TCP_AddSocket(set, ltd->socket) < 0) {
- printf("SDLNet_AddSocket: %s\n", SDLNet_GetError());
- exit(1);
- }
-
- // Keep checking for socket activity while running
- while (ltd->running)
- {
- int numready = SDLNet_CheckSockets(set, 1000);
- printf("numready: %d\n", numready);
- }
-
- SDLNet_FreeSocketSet(set);
-
+ ltd->handler->startListen(ltd);
return 0;
}
@@ -73,10 +54,16 @@ void NetSession::startListen(ConnectionHandler *handler, Uint16 port)
ListenThreadData *data = new ListenThreadData();
- data->address.host = INADDR_ANY;
- data->address.port = port;
data->handler = handler;
data->running = true;
+
+ // Fill in IPaddress for opening local server socket
+ if (SDLNet_ResolveHost(&data->address, NULL, port) == -1) {
+ printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+ exit(6);
+ }
+
+ // Attempt to open the local server socket
data->socket = SDLNet_TCP_Open(&data->address);
if (!data->socket) {
@@ -84,6 +71,7 @@ void NetSession::startListen(ConnectionHandler *handler, Uint16 port)
exit(3);
}
+ // Start the listening thread
data->thread = SDL_CreateThread(startListenThread, data);
if (data->thread == NULL) {