///////////////////////////////////////////////////////////////////////// // connMgr.cpp - connection manager, used by server to manage // // ver 1.1 socket connections // // // // Language: Visual C++, ver 6.0 // // Platform: Dell Dimension 8100, Windows 2000 Pro, SP1 // // Application: CSE691/791 help // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////////// #include #include #include "connMgr.h" using namespace std; /////////////////////////////////////////////////////////////// // initialize static members mtqueue connectionMgr::_deadLetter; mtqueue connectionMgr::_recvQ; connection connectionMgr::conn[MAXCONNECTS]; int connectionMgr::_index = 0; //----< constructor >------------------------------------------ connectionMgr::connectionMgr() { } //----< destructor >------------------------------------------- connectionMgr::~connectionMgr() { } //----< find a connection from ID >---------------------------- int connectionMgr::find(int ID) { for(int i=0; i---------------- int connectionMgr::numConnects() { int sum = 0; for(int i=0; i------------------------------------------- int connectionMgr::makeID() { static int ID = 0; return ID++; } //----< open a new connection >-------------------------------- // // returns ID of new connection // int connectionMgr::openConnection(SOCKET sock) { int ID = connection::failed; for(int i=0; i----------------------------------- void connectionMgr::closeConnection(int ID) { int index = find(ID); if(index < MAXCONNECTS) { conn[index]._state = connection::closed; while(conn[index]._sendQ.length() > 0) _deadLetter.enQ(conn[index]._sendQ.deQ()); return; } cout << "\n couldn't find ID = " << ID; } //----< return a reference to connection's Mutex >------------- // // if connection is open, return its Mutex // otherwise, return the deadLetter queue // Mutex& connectionMgr::locker(int ID) { static Mutex safeMtx; int index = find(ID); if(index < MAXCONNECTS) return conn[index]._mtx; return safeMtx; } //----< return a reference to connection's send queue >-------- // // if connection is open, return its send queue // otherwise, return the deadLetter queue // qRef connectionMgr::sendQ(int ID) { int index = find(ID); if(index < MAXCONNECTS) return conn[index]._sendQ; return _deadLetter; } //----< return a reference to the single receive queue >------- qRef connectionMgr::recvQ() { return _recvQ; } //----< return socket for this connection >-------------------- SOCKET connectionMgr::sock(int ID) { int index = find(ID); if(index < MAXCONNECTS) return conn[index]._sock; return SOCKET_ERROR; } //----< is this connection open? >----------------------------- bool connectionMgr::isOpen(int ID) { int index = find(ID); if(index < MAXCONNECTS) return (conn[index]._state == connection::open); return false; } //----< set enumeration index to top of connection list >------ void connectionMgr::startFindConnection() { _index = 0; } //----< find next open connection >---------------------------- // // returns ID of next connection // int connectionMgr::findNextConnection() { for(int i=_index; i-------------- std::string connectionMgr::stateToStr(connection::connectionState st) { switch(st) { case connection::open : return "open"; case connection::closed : return "closed"; case connection::failed : return "failed"; } return "unknown state"; } //----< display connection status >---------------------------- void connectionMgr::display(int ID) { int index = find(ID); if(index < MAXCONNECTS) { cout << "\n connection " << ID << "\n state = " << stateToStr(conn[index]._state) << "\n SOCKET id = " << conn[index]._sock << "\n #Q'd send msgs = " << conn[index]._sendQ.length() << "\n #Q'd recv msgs = " << _recvQ.length() << endl; } } //----< display all open connections >------------------------- void connectionMgr::displayAll() { int ID; startFindConnection(); while((ID = findNextConnection()) != connection::failed) display(ID); } #ifdef TEST_CONNMGR void main() { cout << "\n Demonstrating connectionMgr class " << "\n ===================================\n"; connectionMgr cm; message msg; SOCKET sock=0; cout << "\n after opening connection on socket " << sock << "\n --------------------------------------\n"; cm.openConnection(sock); cm.startFindConnection(); // test this too int ID0 = cm.findNextConnection(); // and this cm.display(ID0); cout << "\n after enqueing 1 send msg and two recv msgs " << "\n ---------------------------------------------\n"; mtqueue &sendQ = cm.sendQ(ID0); sendQ.enQ(msg); mtqueue &recvQ = cm.recvQ(); recvQ.enQ(msg); recvQ.enQ(msg); cm.display(ID0); cout << "\n extracting a message from receive queue " << "\n -----------------------------------------\n"; message rcvMsg = recvQ.deQ(); cout << "\n message = " << rcvMsg.serialize() << endl; cout << "\n adding two more connections " << "\n -----------------------------\n"; int ID1 = cm.openConnection(1); // 1 is a pseudo socket int ID2 = cm.openConnection(2); // as is 2 cout << "\n number of connects = " << cm.numConnects() << endl; cout << "\n removing a connection " << "\n -----------------------\n"; cout << "\n removing connection " << ID1; cm.closeConnection(ID1); cout << "\n number of connects = " << cm.numConnects() << endl; cm.displayAll(); cout << "\n\n"; } #endif