Worked out networking
authorSam Moore <[email protected]>
Sat, 21 Jan 2012 05:30:52 +0000 (13:30 +0800)
committerSam Moore <[email protected]>
Sat, 21 Jan 2012 05:30:52 +0000 (13:30 +0800)
Wasn't thinking straight with the initial approach

Basically:
 - Each stratego program is running ONE AI program locally
-> That AI's responses need to be sent accross the network to the other stratego program
-> Each stratego program keeps state seperately and sends instructions to its local AI, so actual instructions (ie: "Its your turn") aren't sent
 - A special controller is needed to recieve the responses

So we have NetworkSender, which wraps around an AI_Controller and simply sends its responses (exactly as they are) to the network
and NetworkReceiver which waits for responses from the network.

As far as networking itself is concerned, its not that important who is the Client and who is the Server.
If an IP address is specified, then Client is used, if no IP address is specified, Server is used.

NOTE: It isn't possible to use networking for both AI programs yet.
(ie: stratego @network @network) will fail when the Blue server attempts to bind the socket already used by the Red server.
I may consider fixing this at some point.

Going to test on mufasa.

I've just thought, if the stratego programs have different timeout sequences, there may be problems.
Oh well.

judge/manager/Makefile
judge/manager/ai_controller.h
judge/manager/game.cpp
judge/manager/game.h
judge/manager/graphics.h
judge/manager/main.cpp
judge/manager/network.cpp [new file with mode: 0644]
judge/manager/network.h [new file with mode: 0644]
judge/manager/network_controller.cpp
judge/manager/network_controller.h

index 199a3af..e06e181 100644 (file)
@@ -1,13 +1,13 @@
 #Makefile for Stratego
 
 #Use this to build with graphics
-#LIBRARIES = -lSDL -lGL -lpthread
+LIBRARIES = -lSDL -lGL -lpthread
 #Use this to build without graphics
-LIBRARIES = -lpthread
+#LIBRARIES = -lpthread
 #Use this on Mac OSX (Thanks spartan)
 #LIBRARIES = -I/opt/local/include/ -L/opt/local/lib/ -lSDL -framework OpenGL -lpthread
 CPP = g++ -Wall -pedantic -g
-OBJ = main.o controller.o network_controller.o ai_controller.o human_controller.o program.o thread_util.o stratego.o graphics.o game.o
+OBJ = main.o controller.o network_controller.o ai_controller.o human_controller.o program.o network.o thread_util.o stratego.o graphics.o game.o
 
 BIN = stratego
 
index f4682eb..0a4baeb 100644 (file)
@@ -19,7 +19,11 @@ class AI_Controller : public Controller, private Program
                virtual MovementResult QuerySetup(const char * opponentName,std::string setup[]);
                virtual MovementResult QueryMove(std::string & buffer);
 
-               virtual void Message(const char * message) {Program::SendMessage(message);}
+               virtual void Message(const char * message) 
+               {
+                       //fprintf(stderr, "Sending message \"%s\" to AI program...\n", message);
+                       Program::SendMessage(message);
+               }
                virtual void Pause() {Program::Pause();} //Hack wrapper
                virtual void Continue() {Program::Continue();} //Hack wrapper
 
index 92dc71a..f25c9f3 100644 (file)
@@ -7,7 +7,7 @@ using namespace std;
 Game* Game::theGame = NULL;
 bool Game::gameCreated = false;
 
-Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const  Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime, bool server, bool client) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
+Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const  Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
 {
        gameCreated = false;
        if (gameCreated)
@@ -26,34 +26,24 @@ Game::Game(const char * redPath, const char * bluePath, const bool enableGraphic
        #endif //BUILD_GRAPHICS
 
 
-       if (client)
-       {
-               red = new Client(Piece::RED, "server", redPath); //TODO: Retrieve server address
-       }
-       else
-       {
-               assert(redPath != NULL);
-               if (strcmp(redPath, "human") == 0)
-                       red = new Human_Controller(Piece::RED, graphicsEnabled);
-               else
-                       red = new AI_Controller(Piece::RED, redPath, timeoutTime);
-       }
-       
-       
-       if (server)
-       {
-               blue = new Server(Piece::BLUE, "client");
-       }
-       else
+
+       MakeControllers(redPath, bluePath);
+
+       if (red == NULL || blue == NULL)
        {
-               assert(bluePath != NULL);
-               if (strcmp(bluePath, "human") == 0)
-                       blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+               fprintf(stderr, "Game::Game - Error creating controller: ");
+               if (red == NULL)
+               {
+                       if (blue == NULL)
+                               fprintf(stderr, " BOTH! (red: \"%s\", blue: \"%s\"\n", redPath, bluePath);
+                       else
+                               fprintf(stderr, " RED! (red: \"%s\")\n", redPath);
+               }
                else
-                       blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+                       fprintf(stderr, "BLUE! (blue: \"%s\")\n", bluePath);
+               exit(EXIT_FAILURE);
        }
-
-
+       logMessage("Game initialised.\n");
 }
 
 Game::Game(const char * fromFile, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const  Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
@@ -489,7 +479,7 @@ MovementResult Game::Play()
        
        
 
-
+       logMessage("Messaging red with \"START\"\n");
        red->Message("START");
        
 
@@ -770,4 +760,101 @@ int Game::Tokenise(std::vector<string> & buffer, std::string & str, char split)
        return buffer.size();
 }
 
+/**
+ * Creates Controller baseds off strings. Takes into account controllers other than AI_Controller.
+ * @param redPath - Either the path to an AI_Controller compatable executable, or one of %human or %network or %network:[IP_ADDRESS]
+ * @param bluePath - Ditto
+ * Sets this->red to a controller using redPath, and this->blue to a controller using bluePath
+ * TODO: Make nicer (this function should be ~half the length)
+ */
+void Game::MakeControllers(const char * redPath, const char * bluePath)
+{
+       Network * redNetwork = NULL;
+       Network * blueNetwork = NULL;
+
+       if (redPath[0] == '@')
+       {
+               if (strcmp(redPath, "@human") == 0)
+                       red = new Human_Controller(Piece::RED, graphicsEnabled);
+               else
+               {
+                       const char * network = strstr(redPath, "@network");
+                       if (network == NULL)
+                       {
+                               red = NULL;
+                               return;
+                       }
+                       network = strstr(network, ":");
+               
+                       if (network == NULL)
+                       {
+                               logMessage("Creating server for red AI... ");
+                               redNetwork = new Server();
+                               logMessage("Successful!\n");
+
+                       }
+                       else
+                       {
+                               network = (const char*)(network+1);
+                               logMessage("Creating client for red AI... ");
+                               redNetwork = new Client(network);
+                               logMessage("Connected to address %s\n", network);
+                       }
+
+                       logMessage("    (Red's responses will be received over the connection)\n");
+                       red = new NetworkReceiver(Piece::RED, redNetwork);
+               }               
+       }
+       else
+               red = new AI_Controller(Piece::RED, redPath, timeoutTime);
+
+       if (bluePath[0] == '@')
+       {
+               if (strcmp(bluePath, "@human") == 0)
+                       blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+               else
+               {
+                       const char * network = strstr(bluePath, "@network");
+                       if (network == NULL)
+                       {
+                               blue = NULL;
+                               return;
+                       }
+                       network = strstr(network, ":");
+               
+                       if (network == NULL)
+                       {
+                               logMessage("Creating server for blue AI... ");
+                               blueNetwork = new Server();
+                               logMessage("Successful!\n");
+
+                       }
+                       else
+                       {
+                               network = (const char*)(network+1);
+                               logMessage("Creating client for blue AI... ");
+                               blueNetwork = new Client(network);
+                               logMessage("Connected to address %s\n", network);
+                       }
+                       logMessage("    (Blue's responses will be received over the connection)\n");
+                       blue = new NetworkReceiver(Piece::BLUE, blueNetwork);
+               }               
+       }
+       else
+               blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+
+       if (redNetwork != NULL)
+       {
+               
+               blue = new NetworkSender(Piece::BLUE,blue, redNetwork);
+               logMessage("    (Blue's responses will be copied over the connection)\n");
+       }
+       if (blueNetwork != NULL)
+       {
+               
+               red = new NetworkSender(Piece::RED, red, blueNetwork);
+               logMessage("    (Red's responses will be copied over the connection)\n");
+       }
+       
+}
 
index cc79e65..3f46abb 100644 (file)
@@ -15,7 +15,7 @@
 class Game
 {
        public:
-               Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0, bool server=false, bool client=false);
+               Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0);
                Game(const char * fromFile, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0);
                virtual ~Game();
 
@@ -38,6 +38,9 @@ class Game
 
                static Game * theGame;
                static int Tokenise(std::vector<std::string> & buffer, std::string & str, char split = ' '); //Helper - Split a string into tokens
+
+       private:
+               void MakeControllers(const char * redPath, const char * bluePath); //Create a controller based off a path
        public:
                int logMessage(const char * format, ...);
                FILE * GetLogFile() const {return log;}
index 2a96932..caa57c6 100644 (file)
@@ -1,4 +1,4 @@
-//#define BUILD_GRAPHICS
+#define BUILD_GRAPHICS
 #ifdef BUILD_GRAPHICS
 
 #ifndef GRAPHICS_H
index 08c381c..e65ef0d 100644 (file)
@@ -64,7 +64,7 @@ Piece::Colour SetupGame(int argc, char ** argv)
 {
        char * red = NULL; char * blue = NULL; double stallTime = 0.0; bool graphics = false; bool allowIllegal = false; FILE * log = NULL;
        Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false; double timeoutTime = 2.0;
-       bool server = false; bool client = false;
+
        for (int ii=1; ii < argc; ++ii)
        {
                if (argv[ii][0] == '-')
@@ -185,26 +185,6 @@ Piece::Colour SetupGame(int argc, char ** argv)
                                                system("less manual.txt");
                                                exit(EXIT_SUCCESS);
                                        }
-                                       else if (strcmp(argv[ii]+2, "server") == 0)
-                                       {
-                                               if (client == true)
-                                               {
-                                                       fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n");
-                                                       exit(EXIT_FAILURE);
-                                               }
-                                               server = true;
-                                               
-                                       }
-                                       else if (strcmp(argv[ii]+2, "client") == 0)
-                                       {
-                                               if (server == true)
-                                               {
-                                                       fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n");
-                                                       exit(EXIT_FAILURE);
-                                               }
-                                               client = true;  
-                                               
-                                       }
                                        else
                                        {
                                                fprintf(stderr, "ARGUMENT_ERROR - Unrecognised switch \"%s\"...\n", argv[ii]);
@@ -232,37 +212,16 @@ Piece::Colour SetupGame(int argc, char ** argv)
 
        if (inputFile == NULL)
        {
-               if (server)  
+               if (red == NULL || blue == NULL) //Not enough players
                {
-                       if (red != NULL && blue != NULL)
-                       {
-                               fprintf(stderr, "ARGUMENT_ERROR - When using the --server switch, only supply ONE (1) player.\n");
-                               exit(EXIT_FAILURE);
-                       }
-               }
-               else if (red == NULL || blue == NULL) //Not enough players
-               {
-                       if (client)
-                               fprintf(stderr, "ARGUMENT_ERROR - When using the --client switch, supply an IP for the Red player.\n");
-                       else                    
-                               fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n");      
+                       fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n");      
                        exit(EXIT_FAILURE);     
                }
-               
-               if (client)
-               {
-                       blue = red; red = NULL;
-               }
 
-               Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime, server, client);
+               Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime);
        }
        else
        {
-               if (server || client)
-               {
-                       fprintf(stderr, "ARGUMENT_ERROR - The -f switch is incompatable with the --server or --client switches!\n");
-                       exit(EXIT_FAILURE);
-               }
                Game::theGame = new Game(inputFile, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime);
        }
 
diff --git a/judge/manager/network.cpp b/judge/manager/network.cpp
new file mode 100644 (file)
index 0000000..e349fea
--- /dev/null
@@ -0,0 +1,186 @@
+#include "network.h"
+#include <stdarg.h>
+
+using namespace std;
+
+Network::Network(int newPort) : sfd(-1), port(newPort), file(NULL)
+{
+       sfd = socket(PF_INET, SOCK_STREAM, 0);
+       if (sfd < 0)
+       {
+               perror("Network::Network - Error creating TCP socket");
+               exit(EXIT_FAILURE);
+       }
+}
+
+Network::~Network()
+{
+       if (Valid())
+       {
+               if (shutdown(sfd, SHUT_RDWR) == -1)
+               {
+                       perror("Network::~Network - shutting down socket... ");
+                       close(sfd);
+                       sfd = -1;
+               }
+       }
+       close(sfd);
+}
+
+Server::Server(int newPort) : Network(newPort)
+{
+       struct   sockaddr_in name;
+//     char   buf[1024];
+//     int    cc;
+
+       
+       name.sin_family = AF_INET;
+       name.sin_addr.s_addr = htonl(INADDR_ANY);
+       name.sin_port = htons(port);
+
+       if (bind( sfd, (struct sockaddr *) &name, sizeof(name) ) < 0)
+       {
+               perror("Server::Server - Error binding socket");
+               close(sfd); sfd = -1;
+               exit(EXIT_FAILURE);
+       }
+
+       if (listen(sfd,1) < 0)
+       {
+               perror("Server::Server - Error listening on socket");
+               close(sfd); sfd = -1;
+               exit(EXIT_FAILURE);
+       }
+       int psd = accept(sfd, 0, 0);
+       close(sfd);
+       sfd = psd;
+       if (sfd < 0)
+       {
+               perror("Server::Server - Error accepting connection");
+               close(sfd); sfd = -1;
+               exit(EXIT_FAILURE);
+       }
+
+
+
+       /*
+       for(;;) 
+       {
+               cc=recv(sfd,buf,sizeof(buf), 0) ;
+               if (cc == 0) exit (0);
+               buf[cc] = '\0';
+               printf("message received: %s\n", buf);
+       }
+       */
+}
+
+Client::Client(const char * serverAddress, int newPort) : Network(newPort)
+{
+       struct  sockaddr_in server;
+       struct  hostent *hp;
+
+
+       server.sin_family = AF_INET;
+       hp = gethostbyname(serverAddress);
+       bcopy ( hp->h_addr, &(server.sin_addr.s_addr), hp->h_length);
+       server.sin_port = htons(port);
+
+       if (connect(sfd, (struct sockaddr *) &server, sizeof(server)) < 0)
+       {
+               fprintf(stderr, "Client::Client - Error connecting to server at address %s: ", serverAddress);
+               perror("");
+               close(sfd); sfd = -1;
+               exit(EXIT_FAILURE);
+       }
+
+
+
+
+       /*
+        for (;;) {
+          send(sfd, "HI", 2,0 );
+           sleep(2);
+        }
+       */
+}
+
+/**
+ * Sends a message accross the network
+ * WARNING: Always terminates the message with a newline '\n'
+ * @returns true if the message was successfully sent; false if it was not (ie: the network was not connected!)
+ */
+bool Network::SendMessage(const char * print, ...)
+{
+       if (!Valid()) //Is the process running...
+               return false; 
+
+       if (file == NULL)
+       {
+               file = fdopen(sfd, "r+");
+               setbuf(file, NULL);
+       }
+
+       va_list ap;
+       va_start(ap, print);
+
+       if (vfprintf(file, print, ap) < 0 || fprintf(file, "\n") < 0)
+       {
+               va_end(ap);
+               return false;
+       }
+       va_end(ap);
+
+       return true;
+}
+
+/**
+ * Retrieves a message from the network, waiting a maximum amount of time
+ * @param buffer - C++ string to store the resultant message in
+ * @param timeout - Maximum amount of time to wait before failure. If timeout <= 0, then GetMessage will wait indefinately.
+ * @returns true if the response was recieved within the specified time, false if it was not, or an EOF was recieved, or the process was not running.
+ */
+bool Network::GetMessage(string & buffer, double timeout)
+{
+       if (!Valid() || timeout == 0)
+               return false;
+
+       if (file == NULL)
+       {
+               file = fdopen(sfd, "r+");
+               setbuf(file, NULL);
+       }
+
+       assert(&buffer != NULL);
+       GetterThread getterThread(file, buffer);
+       assert(&(getterThread.buffer) != NULL);
+
+       TimerThread timerThread(timeout*1000000);
+
+       getterThread.Start();
+       if (timeout > 0)
+               timerThread.Start();
+
+       
+       while (!getterThread.Finished())
+       {
+               if (timeout > 0 && timerThread.Finished())
+               {
+                       getterThread.Stop();
+                       timerThread.Stop();
+                       return false;
+               }
+       }
+
+       getterThread.Stop();
+       if (timeout > 0)
+               timerThread.Stop();
+
+       
+
+       if (buffer.size() == 1 && buffer[0] == EOF)
+               return false;
+       return true;
+
+
+}
+
diff --git a/judge/manager/network.h b/judge/manager/network.h
new file mode 100644 (file)
index 0000000..1cd0a11
--- /dev/null
@@ -0,0 +1,53 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <string>
+#include "thread_util.h"
+
+#ifndef NETWORK_H
+#define NETWORK_H
+
+
+class Network
+{
+       public:
+               Network(int newPort = 666);
+               virtual ~Network();
+               bool Valid() const {return sfd != -1;}
+
+               bool SendMessage(const char * print, ...); //Sends a formated message (NOTE: Prints a newline)
+               bool SendMessage(const std::string & buffer) {return SendMessage(buffer.c_str());} //Sends a C++ string message
+               bool GetMessage(std::string & buffer, double timeout=-1); //Retrieves a message, or waits for a timeout (if positive)
+
+       protected:
+               int sfd;
+               int port;
+               FILE * file;
+               
+};
+
+class Server : public Network
+{
+       public:
+               Server(int newPort = 4560);
+               virtual ~Server() {}
+               
+};
+
+class Client : public Network
+{
+       public:
+               Client(const char * server = "127.0.0.1", int newPort = 4560);
+               virtual ~Client() {}
+};
+
+#endif //NETWORK_H
index 9d14676..fcca84e 100644 (file)
 #include "network_controller.h"
 
-NetworkController::NetworkController(const Piece::Colour & newColour, const char * newName) : Controller(newColour, newName), sfd(-1)
-{
-       //struct protoent * tcp = getprotobyname("tcp");
-       sfd = socket(PF_INET, SOCK_STREAM, 0);
-       if (sfd < 0)
-       {
-               perror("NetworkController::NetworkController - Error creating TCP socket");
-               return;
-       }
-}
-
-NetworkController::~NetworkController()
-{
-       if (Valid())
-       {
-               if (shutdown(sfd, SHUT_RDWR) == -1)
-               {
-                       perror("NetworkController::~NetworkController - shutting down socket... ");
-                       close(sfd);
-                       sfd = -1;
-               }
-       }
-       close(sfd);
-}
+using namespace std;
 
-void NetworkController::Message(const char * string)
+MovementResult NetworkSender::QuerySetup(const char * opponentName, string setup[])
 {
+       //fprintf(stderr,"      NetworkSender::QuerySetup... ");
+       MovementResult result = controller->QuerySetup(opponentName, setup);
        
+       for (int ii=0; ii < 4; ++ii)
+               assert(network->SendMessage("%s",setup[ii].c_str())); //TODO: Proper error check
+
+       //fprintf(stderr,"Done!\n");
+       return result;
 }
 
-Server::Server(const Piece::Colour & newColour, const char * newName) : NetworkController(newColour, newName)
+MovementResult NetworkReceiver::QuerySetup(const char * opponentName, string setup[])
 {
-       struct   sockaddr_in name;
-       char   buf[1024];
-       int    cc;
-
-       
-       name.sin_family = AF_INET;
-       name.sin_addr.s_addr = htonl(INADDR_ANY);
-       name.sin_port = htons(NetworkController::port);
-
-       if (bind( sfd, (struct sockaddr *) &name, sizeof(name) ) < 0)
+       //fprintf(stderr,"      NetworkReceiver::QuerySetup... ");
+       for (int ii=0; ii < 4; ++ii)
        {
-               perror("Server::Server - Error binding socket");
-               close(sfd); sfd = -1; return;
-       }
-
-       if (listen(sfd,1) < 0)
-       {
-               perror("Server::Server - Error listening on socket");
-               close(sfd); sfd = -1; return;
-       }
-       int psd = accept(sfd, 0, 0);
-       close(sfd);
-       sfd = psd;
-       if (sfd < 0)
-       {
-               perror("Server::Server - Error accepting connection");
-               close(sfd); sfd = -1; return;
-       }
-
-
-       for(;;) 
-       {
-               cc=recv(sfd,buf,sizeof(buf), 0) ;
-               if (cc == 0) exit (0);
-               buf[cc] = '\0';
-               printf("message received: %s\n", buf);
+               assert(network->GetMessage(setup[ii], 20));
        }
+       //fprintf(stderr,"Done!\n");
+       return MovementResult::OK;
 }
 
-
-Client::Client(const Piece::Colour & newColour, const char * newName, const char * address) : NetworkController(newColour, newName)
+MovementResult NetworkSender::QueryMove(string & buffer)
 {
-       struct  sockaddr_in server;
-       struct  hostent *hp;
-
-
-       server.sin_family = AF_INET;
-       hp = gethostbyname("127.0.0.1");
-       bcopy ( hp->h_addr, &(server.sin_addr.s_addr), hp->h_length);
-       server.sin_port = htons(NetworkController::port);
-
-       if (connect(sfd, (struct sockaddr *) &server, sizeof(server)) < 0)
-       {
-               perror("Client::Client - Error connecting to server at address %s");
-               close(sfd); sfd = -1;
-               return;
-       }
-
-        for (;;) {
-          send(sfd, "HI", 2,0 );
-           sleep(2);
-        }
-
+       MovementResult result = controller->QueryMove(buffer);
+       network->SendMessage("%s", buffer.c_str());
+       return result;
 }
-//EOF
-
 
+MovementResult NetworkReceiver::QueryMove(string & buffer)
+{
+       assert(network->GetMessage(buffer, 20));
+       return MovementResult::OK;
+}
index 7b9af30..31b0c92 100644 (file)
@@ -1,51 +1,57 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <errno.h>
-
-
 #include "controller.h"
+#include "ai_controller.h"
+#include "human_controller.h"
+#include "network.h"
 
 #ifndef NETWORK_CONTROLLER_H
 #define NETWORK_CONTROLLER_H
 
-
 class NetworkController : public Controller
 {
        public:
-               NetworkController(const Piece::Colour & newColour, const char * newName = "no-name");
-               virtual ~NetworkController();
+               NetworkController(const Piece::Colour & colour, Network * newNetwork) : Controller(colour), network(newNetwork) {}
+               virtual ~NetworkController() {}
 
-               virtual bool Valid() {return sfd != -1;}
-
-               virtual void Message(const char * string);
-               virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
-               virtual MovementResult QueryMove(std::string & buffer) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
+               //virtual void Message(const char * message) = 0; 
+               virtual bool Valid() const {return network->Valid();}
 
        protected:
-               int sfd; int cfd;
-               static const int port = 4950;   
+               Network * network;
 };
 
-class Server : public NetworkController
+class NetworkSender : public NetworkController
 {
        public:
-               Server(const Piece::Colour & newColour, const char * newName = "no-name");
-               virtual ~Server() {}
+               NetworkSender(const Piece::Colour & colour, Controller * newController, Network * newNetwork) : NetworkController(colour, newNetwork), controller(newController) {}
+               virtual ~NetworkSender() {delete controller;}
+
+               virtual bool Valid() const {return NetworkController::Valid() && controller->Valid();}
+
+               virtual void Message(const char * message) 
+               {
+                       //fprintf(stderr,"NetworkSender sending message %s to underlying controller\n", message);
+                       controller->Message(message);
+               }
+
+               virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]);
+               virtual MovementResult QueryMove(std::string & buffer);
+
+       private:
+               Controller * controller;
+
 };
 
-class Client : public NetworkController
+class NetworkReceiver : public NetworkController
 {
        public:
-               Client(const Piece::Colour & newColour, const char * newName = "no-name", const char * server="127.0.0.1");
-               virtual ~Client() {}
+               NetworkReceiver(const Piece::Colour & colour, Network * newNetwork) : NetworkController(colour, newNetwork) {}
+               virtual ~NetworkReceiver() {}
+
+               virtual void Message(const char * message) {} //Do nothing (Counter intuitive much)
+               virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]);
+               virtual MovementResult QueryMove(std::string & buffer);
+               
+
 };
 
 #endif //NETWORK_CONTROLLER_H

UCC git Repository :: git.ucc.asn.au