void ClientCollection::Login_Logout() { int command = 0; //Client *CurrentUser = new Client(1, "guest"); cout << "1. 로그인" << endl; cout << "2. 로그아웃" << endl; cout << "0. 메인 메뉴로 돌아가기" << endl; cout << "* 입력 선택 : "; cin >> command; cin.clear(); cin.ignore(256, '\n'); bool loginCheck = false; loginCheck = (CurrentUser.getId() == "!!!"); switch (command) { case 1: cout << "************** 로그인 하러 오셨군요 반갑습니다 **************" << endl; if (loginCheck == true){ if (ClientCollect.Login() == true) { cout << "로그인 성공" << endl; } else { cout << "로그인 실패" << endl; } } else { cout << "이미 로그인 상태 입니다!!" << endl; } break; case 2: cout << "************** 로그아웃 하러 오셨군요 **************" << endl; if (loginCheck == false) { if (ClientCollect.Logout() == true) { cout << "로그아웃 완료" << endl; } else cout << "로그아웃 취소" << endl; } else cout << "로그아웃이 불가능 합니다. 로그인을 먼저 해주세요!!!" << endl; break; case 0: cout << "메인 메뉴로 돌아갑니다." << endl; return; break; default: cout << "알맞지 않는 번호입니다"; break; } }
void ClientCollection::signUp_deleteClient() { int command = 0; cout << "1. 회원 가입" << endl; cout << "2. 회원 탈퇴" << endl; cout << "0. 메인 메뉴로 돌아가기" << endl; cout << "* 입력 선택 : "; cin >> command; cin.clear(); cin.ignore(256, '\n'); switch (command) { case 1: cout << "************** 회원가입 하러 오셨군요 반갑습니다 **************" << endl; if (CurrentUser.getId() != "!!!"){ cout << "로그아웃 후 가입이 가능합니다." << endl; } else { ClientCollect.signUp(); cout << "회원 가입이 완료되었습니다." << endl; } break; case 2: cout << "************** 회원탈퇴 하러 오셨군요 반갑습니다 **************" << endl; // CurrentUser만이 탈퇴가 가능하다 if (CurrentUser.getId() == "!!!") { cout << "로그인 후 탈퇴가 가능합니다." << endl; } else{ if (ClientCollect.deleteClient(CurrentUser) == true) { cout << "탈퇴가 완료되었습니다." << endl; } else { cout << "탈퇴가 취소되었습니다." << endl; } } break; case 0: cout << "메인 메뉴로 돌아갑니다." << endl; return; break; default: cout << "잘못된 값을 입력하셨습니다. 다시 입력해주세요"; break; } }
void Message::send_to(const ClientCollection &clients, int32_t document_id) const { // generate bytestream to send std::vector<char> bytestream; generate_bytestream(bytestream); // send clients.broadcast(bytestream, document_id); }
// client's reader thread. The server writes to its socket! void *readerThread( void *sID ){ int sockID = *( reinterpret_cast<int *>( sID ) ); pthread_mutex_unlock( &accept_mutex ); int name_ok, n, msgsize = 0; string clientName, msg; char username[ CLIENT_NAME_LEN + 1 ]; Client *client; cout << "rThread(" << pthread_self() << "): Reading username...\n"; if( ( readN( sockID, username, CLIENT_NAME_LEN ) ) < 0 ){ cout << "rThread(" << pthread_self() << "): Read error.\n"; exit( 10 ); } clientName = username; if( ( client = allClients.exists( clientName ) ) == NULL ){ name_ok = NAME_NOT_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "rThread(" << pthread_self() << "): Write error.\n"; exit( 11 ); } pthread_exit( NULL ); } name_ok = NAME_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "rThread(" << pthread_self() << "): Write error.\n"; exit( 12 ); } client->setReaderSockDesc( sockID ); while( !client->isActive() ); // send the size of the outgoing message while( ( writeN( sockID, ( char * ) &msgsize, sizeof( msgsize ) ) ) > 0 ){ // send the message to the client if( ( n = writeN( sockID, ( char * ) msg.c_str(), msgsize ) ) < 0 ){ cout << "rThread(" << pthread_self() << "): Write error.\n"; exit( 13 ); } msg = client->readChatMessage(); msgsize = msg.length(); msg[ msgsize ] = '\0'; } client->closeReader(); pthread_exit( NULL ); }
//REvesion // 6/20 1:20 am 전주라 //privateNumber 정보를 추가하였다. void ClientCollection::signUp() { string str; Client newClient; int checkNum = 0; int newMember = 0; for (; totalClient[newMember].getId() != "!!!"; newMember++); try { cout << "name 입력(15자 이하 가능) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() > 15) throw 1; newClient.setName(str);//몇 번째 값에 Name을 설정할 것인지 정하는 함수입니다 cout << "address 입력(30자 이하 가능) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() > 30) throw 2; newClient.setAddress(str); cout << "email 입력(30자 이하 가능) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() > 30) throw 3; newClient.setEmail(str); cout << "id 입력(15자 이하 가능) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() > 15) throw 4; while (checkNum < 10) { if (totalClient[checkNum].getId() == str) break; checkNum++; } if (checkNum != 10) { cout << "중복된 id가 있습니다." << endl; return; } // 중복된 id가 없는 경우 회원가입이 진행됩니다. newClient.setId(str); cout << "password 입력(20자 이하 가능) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() > 20) throw 5; newClient.setPassword(str); cout << "privateNumber주민번호 입력(13자) : "; cin >> str; cin.clear(); cin.ignore(256, '\n'); if (str.length() != 13) throw 6; newClient.setAddress(str); newClient.setEnrollNumber(newMember); ClientCollect.setTotalClient(newMember, newClient); cout << "회원 가입이 완료되었습니다." << endl; } catch (int type) { switch (type) { case 1: cout << "name은 15자를 넘어갈 수 없습니다." << endl; break; case 2: cout << "address는 30자를 넘어갈 수 없습니다." << endl; break; case 3: cout << "email은 30자를 넘어갈 수 없습니다." << endl; break; case 4: cout << "id는 15자를 넘어갈 수 없습니다." << endl; break; case 5: cout << "password는 20자를 넘어갈 수 없습니다." << endl; break; case 6: cout << "privateNumber는 13자입니다." << endl; break; default: break; } } return; }
// client's writer thread. The server reads from it. void *writerThread( void *sID ){ int sockID = *( reinterpret_cast<int *>( sID ) ); pthread_mutex_unlock( &accept_mutex ); int name_ok, n, msgsize = 0; string clientName, msg, nametag, fullmsg; char username[ CLIENT_NAME_LEN + 1 ]; char buff[ MAXLINE ]; Client *client; cout << "wThread(" << pthread_self() << "): Reading username...\n"; if( ( readN( sockID, username, CLIENT_NAME_LEN ) ) < 0 ){ cout << "wThread(" << pthread_self() << "): Read error.\n"; exit( 14 ); } clientName = username; if( ( client = allClients.exists( clientName ) ) == NULL ){ name_ok = NAME_NOT_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "wThread(" << pthread_self() << "): Write error.\n"; exit( 15 ); } pthread_exit( NULL ); } name_ok = NAME_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "wThread(" << pthread_self() << "): Write error.\n"; exit( 16 ); } client->setWriterSockDesc( sockID ); nametag = "["; nametag += clientName; nametag += "]"; for( int i = 0; i < ( CLIENT_NAME_LEN - clientName.length() ); i++ ) nametag += " "; nametag += "> "; while( !client->isActive() ); memset( buff, '\0', MAXLINE ); // get the size of the incoming message while( ( readN( sockID, ( char * ) &msgsize, sizeof( msgsize ) ) ) > 0 ){ // read msg from the client's writer process if( ( n = readN( sockID, buff, msgsize ) ) < 0 ){ cout << "wThread(" << pthread_self() << "): Read error.\n"; exit( 17 ); } msg = buff; fullmsg = nametag; fullmsg += msg; client->postMessageToDefaultChatRoom( fullmsg ); memset( buff, '\0', MAXLINE ); } client->closeWriter(); pthread_exit( NULL ); }
void *commandThread( void *sID ){ int sockID = *( reinterpret_cast<int *>( sID ) ); pthread_mutex_unlock( &accept_mutex ); int name_ok, n, cmdsize = COMMAND_LEN, cmdstatus, wbsize; bool valid, write_back; string clientName, comstr, comhead = "", comarg = "", wbmessage; char username[ CLIENT_NAME_LEN + 1 ]; char buff[ MAXLINE ]; Client *client; cout << "cThread(" << pthread_self() << "): Reading username...\n"; if( ( readN( sockID, username, CLIENT_NAME_LEN ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Read error.\n"; exit( 6 ); } clientName = username; if( allClients.exists( clientName ) ){ name_ok = NAME_NOT_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Write error.\n"; exit( 7 ); } pthread_exit( NULL ); } name_ok = NAME_AVAILABLE; name_ok = htons( name_ok ); if( ( writeN( sockID, ( char * ) &name_ok, sizeof( name_ok ) ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Write error.\n"; exit( 8 ); } client = new Client( clientName, defaultChatRoom ); defaultChatRoom->addClient( client ); client->setCommandSockDesc( sockID ); allClients.addClient( client ); while( !client->isActive() ); memset( buff, '\0', MAXLINE ); // first, read the size of the command while( ( readN( sockID, ( char * ) &cmdsize, sizeof( cmdsize ) ) ) > 0 ){ // then, read the command if( ( n = readN( sockID, buff, cmdsize ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Read error.\n"; exit( 9 ); } comstr = buff; cout << "cThread(" << pthread_self() << "): " << comstr << "\n"; // In order to keep the internals consistent across clients, we lock this region pthread_mutex_lock( &command_mutex ); // first pass - see if the command has the right number of characters valid = true; write_back = false; if( comstr.length() > 3 ){ for( int i = 0; i < 4; i++ ) comhead += comstr[i]; } else valid = false; if( comhead != "bye." && comhead != "shut" && comhead != "lscr" && comhead != "lssu" && comhead != "myde" ) if( comstr.length() > 5 ) for( int j = 5; j < comstr.length(); j++ ) comarg += comstr[j]; else valid = false; // second pass - interpret the command if( valid ){ // "bye." - client wishes to exit the server if( comhead == "bye." ){ allChatRooms.wipeClient( client->getID() ); allClients.deleteClient( client->getID() ); client->closeReader(); client->closeWriter(); } // "crea" - CREAte a new chatroom else if( comhead == "crea" ){ ChatRoom *newRoom = new ChatRoom( comarg ); if( !allChatRooms.addChatRoom( newRoom ) ) valid = false; else dispatch( newRoom ); } // "subs" - SUBScribe to an existing chatroom else if( comhead == "subs" ){ ChatRoom *newRoom; if( newRoom = allChatRooms.exists( comarg ) ) if( !newRoom->addClient( client ) ) valid = false; else; else valid = false; } // "unsu" - UNSUbscribe from a given chatroom else if( comhead == "unsu" ){ ChatRoom *newRoom; if( newRoom = allChatRooms.exists( comarg ) ) if( newRoom->removeClient( client->getID() ) ) if( !newRoom->numClients() && newRoom->getRoomName() != "Default" ){ allChatRooms.deleteChatRoom( comarg ); // Below should trigger the clean-up of the ChatRoom's consumer threads newRoom = NULL; } else; else valid = false; else valid = false; } // "shut" - SHUT the server down else if( comhead == "shut" ){ } // "myde" - displays the client's default chatroom else if( comhead == "myde" ){ wbmessage = "(None)\n"; if( client->getDefaultChatRoom() ){ wbmessage = client->getDefaultChatRoom()->getRoomName(); wbmessage += '\n'; } write_back = true; } // "defa" - change the client's DEFAult chatroom; this is where the client's messages are sent else if( comhead == "defa" ){ ChatRoom *newRoom; if( newRoom = allChatRooms.exists( comarg ) ){ client->setDefaultChatRoom( newRoom ); newRoom->addClient( client ); } else valid = false; } // "lscr" - provide a LIst of all existing ChatRooms else if( comhead == "lscr" ){ wbmessage = allChatRooms.lscr(); write_back = true; } // "lssu" - provide a LIst of chatrooms to which this client has SUbscribed else if( comhead == "lssu" ){ wbmessage = allChatRooms.lssu( client->getID() ); write_back = true; } else valid = false; } if( valid ) if( write_back ) cmdstatus = COMMAND_WRITE_BACK; else cmdstatus = COMMAND_ACCEPTED; else cmdstatus = COMMAND_NOT_ACCEPTED; if( ( writeN( sockID, ( char * ) &cmdstatus, sizeof( cmdstatus ) ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Write error.\n"; exit( 10 ); } if( cmdstatus == COMMAND_WRITE_BACK ){ wbsize = wbmessage.length(); if( ( writeN( sockID, ( char * ) &wbsize, sizeof( wbsize ) ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Write error.\n"; exit( 11 ); } if( ( writeN( sockID, ( char * ) wbmessage.c_str(), wbsize ) ) < 0 ){ cout << "cThread(" << pthread_self() << "): Write error.\n"; exit( 12 ); } } pthread_mutex_unlock( &command_mutex ); comhead = ""; comarg = ""; wbmessage = ""; memset( buff, '\0', MAXLINE ); } // clean up! pthread_exit( NULL ); }