1 / 31

COMP 150-IDS Ping Demonstration Programs & Makefile / C++ Hints

COMP 150-IDS: Internet Scale Distributed Systems (Fall 2013). COMP 150-IDS Ping Demonstration Programs & Makefile / C++ Hints. Noah Mendelsohn Tufts University Email: noah@cs.tufts.edu Web: http://www.cs.tufts.edu/~noah. What you should get from today’s session.

sailor
Télécharger la présentation

COMP 150-IDS Ping Demonstration Programs & Makefile / C++ Hints

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. COMP 150-IDS: Internet Scale Distributed Systems (Fall 2013) COMP 150-IDSPing Demonstration Programs&Makefile / C++ Hints Noah Mendelsohn Tufts UniversityEmail: noah@cs.tufts.edu Web: http://www.cs.tufts.edu/~noah

  2. What you should get from today’s session • A quick look at some details you’ll need to do our programming assignment, including: • The framework we’re using • C++ Exceptions • A tiny bit about inheritance • Makefiles • C/C++ tips and tricks

  3. Working through the Demo Client

  4. Include Framework and Debug code Preamble #include "c150dgmsocket.h" #include "c150debug.h" #include <fstream> using namespace std; // for C++ std library using namespace C150NETWORK;

  5. IMPORTANT!Needed for COMP150IDS Framework! Preamble #include "c150dgmsocket.h" #include "c150debug.h" #include <fstream> using namespace std; // for C++ std library using namespace C150NETWORK;

  6. Main pingclient Logic

  7. This is not an ordinary socket…it’s a smart wrapper around a socket Client logic Establishes us as a client…and identifies the server…ports set based on login id try { C150DgmSocket *sock = new C150DgmSocket(); sock -> setServerName(argv[serverArg]); sock -> write(argv[msgArg], strlen(argv[msgArg])+1); readlen = sock -> read(incomingMessage, sizeof(incomingMessage)); checkAndPrintMessage(readlen, incomingMessage, sizeof(incomingMessage)); } catch (C150NetworkException e) { cerr << argv[0] << ": caught C150NetworkException: " << e.formattedExplanation() << endl; }

  8. Clients write,then read Client logic try { C150DgmSocket *sock = new C150DgmSocket(); sock -> setServerName(argv[serverArg]); sock -> write(argv[msgArg], strlen(argv[msgArg])+1); readlen = sock -> read(incomingMessage, sizeof(incomingMessage)); checkAndPrintMessage(readlen, incomingMessage, sizeof(incomingMessage)); } catch (C150NetworkException e) { cerr << argv[0] << ": caught C150NetworkException: " << e.formattedExplanation() << endl; }

  9. Demo Server

  10. Servers read, then write Server logic try { C150DgmSocket *sock = new C150DgmSocket(); c150debug->printf(C150APPLICATION,"Ready to accept messages"); while(1) { readlen = sock -> read(incomingMessage, sizeof(incomingMessage)-1); // … WORK WITH MESSAGE HERE string response = “SOME RESPONSE HERE”; sock -> write(response.c_str(), response.length()+1); } } catch (C150NetworkException e) { c150debug->printf(C150ALWAYSLOG,"Caught C150NetworkException: %s\n", e.formattedExplanation().c_str()); }

  11. Server logic Framework assumes responses go to server/port from which we read try { C150DgmSocket *sock = new C150DgmSocket(); c150debug->printf(C150APPLICATION,"Ready to accept messages"); while(1) { readlen = sock -> read(incomingMessage, sizeof(incomingMessage)-1); // … WORK WITH MESSAGE HERE string response = “SOME RESPONSE HERE”; sock -> write(response.c_str(), response.length()+1); } } catch (C150NetworkException e) { c150debug->printf(C150ALWAYSLOG,"Caught C150NetworkException: %s\n", e.formattedExplanation().c_str()); }

  12. Inferring who is a server and who is a client NOTE: The socket class imposes a simple notion of client/server on UDP… It decides whether you’re a server or client based on which methods you call first 1) client calls setServer name then writes 2) server starts by doing a read. Note a very robust approach for production code, but handy for these simple programs. try { C150DgmSocket *sock = new C150NastyDgmSocket(nastiness); c150debug->printf(C150APPLICATION,"Ready to accept messages"); while(1) { readlen = sock -> read(incomingMessage, sizeof(incomingMessage)-1); // … WORK WITH MESSAGE HERE string response = “SOME RESPONSE HERE”; sock -> write(response.c_str(), response.length()+1); } } catch (C150NetworkException e) { c150debug->printf(C150ALWAYSLOG,"Caught C150NetworkException: %s\n", e.formattedExplanation().c_str()); }

  13. C++ Inheritance

  14. Base class “Shape” has draw() method with no implementation (=0) A super-simple look at C++ Inheritance class Shape { private: Point position; public: Point getPosition(); virtual void draw() = 0; };

  15. A super-simple look at C++ Inheritance class Shape { private: Point position; public: Point getPosition(); virtual void draw() = 0; }; Each subclass provides its own implementation of draw() Class Circle : public Shape { public: virtual void draw(); }; Class Square : public Shape { public: virtual void draw(); };

  16. Both classes inherit postion() method from parent A super-simple look at C++ Inheritance Class shape { private: Point position; public: Point getPosition(); virtual void draw() = 0; }; Shape *shapeArray[2]; inti; shapeArray[0] = new Circle(); • shapeArray[1] = new Square(); • for(i=0; i<2; i++) { • cout << • shapeArray[i] -> position; • shapeArray[i] -> draw(); • } Class Circle : public Shape { public: virtual void draw(); }; Class Square : public Shape { public: virtual void draw(); };

  17. First time calls Circle::draw,second time calls Square::draw A super-simple look at C++ Inheritance Class shape { private: Point position; public: Point getPosition(); virtual void draw() = 0; }; Shape *shapeArray[2]; inti; shapeArray[0] = new Circle(); • shapeArray[1] = new Square(); • for(i=0; i<2; i++) { • cout << • shapeArray[i] -> position; • shapeArray[i] -> draw(); • } Class Circle : public Shape { public: virtual void draw(); }; Class Square : public Shape { public: virtual void draw(); };

  18. The C150NastyDgmSocket class inherits from… Inheritance and nasty sockets logic try { C150DgmSocket *sock = new C150NastyDgmSocket(nastiness); c150debug->printf(C150APPLICATION,"Ready to accept messages"); while(1) { readlen = sock -> read(incomingMessage, sizeof(incomingMessage)-1); // … WORK WITH MESSAGE HERE string response = “SOME RESPONSE HERE”; sock -> write(response.c_str(), response.length()+1); } } catch (C150NetworkException e) { c150debug->printf(C150ALWAYSLOG,"Caught C150NetworkException: %s\n", e.formattedExplanation().c_str()); } … C150DgmSocket. You can use either type here, unless you want to call methods specific to the “nasty” class.

  19. C++ Exceptions

  20. C++ Exceptions C++ has try/catch/throw for Exceptions try clause runs first try{ C150DgmSocket *sock = new C150DgmSocket(); sock -> setServerName(argv[serverArg]); sock -> write(argv[msgArg], strlen(argv[msgArg])+1); readlen = sock -> read(incomingMessage, sizeof(incomingMessage)); checkAndPrintMessage(readlen, incomingMessage, sizeof(incomingMessage)); } catch (C150NetworkException e) { cerr << argv[0] << ": caught C150NetworkException: " << e.formattedExplanation() << endl; } Any network exception in try block or methods called by try block takes us here e is of whatevertype was “thrown”

  21. C++ Exceptions • Exceptions are particularly useful for network code… • …no need to “percolate” return codes through layers of method calls • Standard COMP 150IDS Exception Class:throw throw C150NetworkException("Client received message that was not null terminated");When an error occurs, throw an Exception (same as “raise” in other langs):throw C150NetworkException (or other class) • Exception classes form a hierarchy…based on class inheritance (no need for you to worry about that if you don’t know C++ inheritance)

  22. MakefilesDependency –based Command Execution

  23. Makefile variables Variables defined this way… # Do all C++ compies with g++ CPP = g++ CPPFLAGS = -g -Wall -Werror -I$(C150LIB) # Where the COMP 150 shared utilities live, including c150ids.a and userports.csv # Note that environment variable COMP150IDS must be set for this to work! C150LIB = $(COMP150IDS)/files/c150Utils/ [… several lines skipped…] pingclient: pingclient.o $(C150AR) $(INCLUDES) $(CPP) -o pingclient pingclient.o …or from environment…(this is one reason yousetenv COMP150IDS /comp/150IDS) …used this way

  24. Targets and dependencies The pingclient target # Do all C++ compies with g++ CPP = g++ CPPFLAGS = -g -Wall -Werror -I$(C150LIB) # Where the COMP 150 shared utilities live, including c150ids.a and userports.csv # Note that environment variable COMP150IDS must be set for this to work! C150LIB = $(COMP150IDS)/files/c150Utils/ [… several lines skipped…] pingclient: pingclient.o $(C150AR) $(INCLUDES) $(CPP) -o pingclient pingclient.o …depends onpingclient.o (and include files, etc.)

  25. What gets run When pingclient is older than pingclient.o, etc. … # Do all C++ compies with g++ CPP = g++ CPPFLAGS = -g -Wall -Werror -I$(C150LIB) # Where the COMP 150 shared utilities live, including c150ids.a and userports.csv # Note that environment variable COMP150IDS must be set for this to work! C150LIB = $(COMP150IDS)/files/c150Utils/ [… several lines skipped…] pingclient: pingclient.o $(C150AR) $(INCLUDES) $(CPP) -o pingclient pingclient.o ..use g++ to relink it

  26. Fancier dependencies Each xxx.o file …depends on xxx.cpp %.o:%.cpp $(INCLUDES) $(CPP) -c $(CPPFLAGS) $< …and is compiled from that .cpp file

  27. C cs. C++ Strings

  28. C vs C++ Strings – we use both! • C++ provides automatic allocation and useful concatenation operations • C char[] arrays needed for formatting message packets • File and socket APIs defined in terms of C byte arrays • Also…preference • For some purposes, printf/scanf are handier than C++ << • Etc.

  29. Some hints on strings • Won’t try a full tutorial here but, remember that you can convert:char cstring[4] = “abc”; // remember the null! string newstring(cstring); // initialize C++ string // from C string char *fromCPlusPlus = newstring.c_str(); // IMPORTANT: fromCPlusPlus // is stable ONLY until // next change to newstring • Our focus is on the distributed system design…performance matters some, but do what’s easy and clean

  30. Stringstreams: useful for formatting and conversions • C++ strings do not support <<, but stringstreams doinclude <sstream> // for stringstream include <iostream> // for cout stringstream ss; // empty stringstream int answer = 25; ss << “The answer is “<< answer << “ pounds” << endl; cout << ss.str(); // get string from stringstream

  31. What I Do (mostly) • I mostly use C++ strings: automatic allocation • I use or convert to char[] if I’m using APIs that need them • I use either printf or stringstreams for formatting or… • …concatenate strings with “+” (slower, and edge cases where it doesn’t work) • Not all the framework code makes good choices internally…you’ll find some stuff that probably should be cleaned up (e.g. excess conversions)

More Related