int main( int argc, char* argv[]) { // create the context on the stack Context ct; // init the context ct.Init(); // set the run state ct.m_Running = true; // create the input thread ct.m_InputThread = ct.MakeThread(InputThread); ct.m_InputThread->m_Type = LocalContext::T_INPUT; bool success = true; // create the TCP thread ct.m_TCPThread = ct.MakeThread(TCPRecvThread); ct.m_TCPThread->m_Sockfd = -1; ct.m_TCPThread->m_Type = LocalContext::T_TCP; ct.m_TCPThread->m_Mutex = ct.m_TCPMutex; /* // create the UDP thread ct.m_TCPThread = ct.MakeThread(RecvThread); ct.m_TCPThread->m_Sockfd = -1; ct.m_TCPThread->m_Type = LocalContext::T_TCP; */ // create the TTY thread ct.m_TTYThread = ct.MakeThread(TTYRecvThread); ct.m_TTYThread->m_Sockfd = -1; ct.m_TTYThread->m_Type = LocalContext::T_TTY; ct.m_TTYThread->m_Mutex = ct.m_TTYMutex; LogMsgToTerminal("INITIALIZATION COMPLETE"); // start the loop pthread_mutex_lock(&(ct.m_PollMutex)); while( ct.m_Running ) { // wait on the condition pthread_cond_wait(&(ct.m_PollCondition), &(ct.m_PollMutex)); // access the thread context LocalContext* tLct = ct.FindThread( ct.m_Caller ); if( tLct == NULL ) continue; // no thread context... // do work stringstream ss; // check the caller if( ct.m_Caller == 1 ) // called from the input thread { // simple: broadcast the input thread string to the server // make sure we have a valid connection, and // this was not an exit command if( success && ct.m_Running ) { // send the message //LogMsgToTerminal( tLct->m_MSG ); //size_t sent = send( sockfd, tLct->m_MSG.c_str(), tLct->m_MSG.length(), 0 ); } } else // called from recv thread { // the recv threads // simply log the message to the screen LogMsgToTerminal(tLct->m_MSG); } } pthread_mutex_unlock(&(ct.m_PollMutex)); // clean up the socket if( (ct.m_TCPThread)->m_Sockfd >= 0 ) { close((ct.m_TCPThread)->m_Sockfd); } // destroy and join the threads ct.DestroyAllThreads(); // shut down the context ct.Shutdown(); return 0; }
int main( int argc, char* argv[]) { // create the context on the stack Context ct; // get the input, exit if failure if( !GetInput(&ct, argc, argv) ) return 0; // init the context ct.Init(); // set the run state ct.m_Running = true; // create the input thread ct.MakeThread(InputThread); // check the mode if( ct.m_Mode == 1 ) { // create the server ct.MakeThread(ListenThread); } // some variables for sockets int sockfd; struct sockaddr_in saLoc; bool success = true; // lets do some socket creation (for the client) if( ct.m_Mode == 2 ) { // place this in a for loop to create a breakable scope for(int dum = 0; dum < 1; dum++) { //Create a reliable, stream socket using TCP if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { LogMsgToTerminal("ERROR CREATING SOCKET"); success = false; break; } // Local int yes = 1; memset(&saLoc, 0, sizeof(struct sockaddr_in)); saLoc.sin_family = AF_INET; // Internet address family saLoc.sin_port = htons(ct.m_SPort); // the local port saLoc.sin_addr.s_addr = inet_addr("127.0.0.1"); // the local IP Addr // let the kernel know we are willing to reuse the socket if still around setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); if( bind(sockfd, (struct sockaddr *)&saLoc, sizeof(struct sockaddr)) < 0 ) { LogMsgToTerminal("ERROR BINDING SOCKET"); success = false; close(sockfd); break; } // set the destination parameters - the IP is already set ct.m_Sa.sin_family = AF_INET; // Internet address family ct.m_Sa.sin_port = htons(ct.m_DPort); // Server port LogMsgToTerminal("ATTEMPTING TO CONNECT"); if (connect(sockfd, (struct sockaddr*) &(ct.m_Sa),sizeof(ct.m_Sa)) < 0) { LogMsgToTerminal("ERROR CONNECTING"); success = false; break; } else { LogMsgToTerminal("SUCCESSFULL CONNECTION"); // set the socket to non-blocking // and create the recv thread struct timeval timeout; timeout.tv_sec = 10; timeout.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); // now lets add the new socket LocalContext* newCT = ct.MakeThread(RecvThread); newCT->m_Sockfd = sockfd; } } } // start the loop pthread_mutex_lock(&(ct.m_PollMutex)); while(ct.m_Running) { // wait on the condition pthread_cond_wait(&(ct.m_PollCondition), &(ct.m_PollMutex)); // access the thread context LocalContext* tLct = ct.FindThread( ct.m_Caller ); if( tLct == NULL ) continue; // no thread context... // do work stringstream ss; // check the caller if( ct.m_Caller == 1 ) { // the input thread // switch on mode switch( ct.m_Mode ) { case 1: // server // broadcast to all recv threads ss << ct.m_DPort << ": " << tLct->m_MSG; ct.BroadcastAll( ss.str() ); break; case 2: // client // simple: broadcast the input thread string to the server // make sure we have a valid connection, and // this was not an exit command if( success && ct.m_Running ) { // send the message LogMsgToTerminal( tLct->m_MSG ); size_t sent = send( sockfd, tLct->m_MSG.c_str(), tLct->m_MSG.length(), 0 ); } break; } } else { // the recv threads // switch on mode switch( ct.m_Mode ) { case 1: // server // log the message and transmit ss << GetPortFromStruct( &(tLct->m_Addr) ); ss << ": " << tLct->m_MSG; LogMsgToTerminal(ss.str()); ct.BroadcastAll( ss.str(), ct.m_Caller ); break; case 2: // client // simply log the message to the screen LogMsgToTerminal(tLct->m_MSG); break; } } } pthread_mutex_unlock(&(ct.m_PollMutex)); // clean up the socket if( ct.m_Mode == 2 ) { if( success ) { close(sockfd); } } // destroy and join the threads ct.DestroyAllThreads(); // shut down the context ct.Shutdown(); return 0; }