bool SocketAcceptor::onData( SocketServer& server, socket_handle s ) { SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return false; SocketConnection* pSocketConnection = i->second; return pSocketConnection->read( *this, server ); }
bool SocketInitiator::onData( SocketConnector& connector, int s ) { QF_STACK_PUSH(SocketInitiator::onData) SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return false; SocketConnection* pSocketConnection = i->second; return pSocketConnection->read( connector ); QF_STACK_POP }
void SocketServer::start() { struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; char remoteIP[INET6_ADDRSTRLEN]; // sigset_t mask; // sigset_t orig_mask; // key = connection id std::map<int, SocketConnection*> connections; // /** // * I'm not sure of this signal handling code, but for now it works: // * I register a signal handler for the process, then in the handler I look if it's a SIGKILL for the thread, then // * flag it as killed. // * The sigmask code, I think, it's for handling correctly a signal while pselect is waiting, then exit from it // */ // struct sigaction act; // // memset (&act, 0, sizeof(act)); // act.sa_handler = signal_handler; // // /* should shut down on SIGTERM. */ // if (sigaction(SIGTERM, &act, 0)) { // perror ("sigaction"); // throw std::exception(); // } // // sigemptyset (&mask); // sigaddset (&mask, SIGPIPE); // // if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) { // perror ("sigprocmask"); // throw std::exception(); // } // main loop for(;;) { read_fds = master; // copy it if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } int i; // run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listenfd) { // handle new connection addrlen = sizeof remoteaddr; int connfd = accept(listenfd, (struct sockaddr *)&remoteaddr, &addrlen); if (connfd == -1) { perror("accept() error"); } else { FD_SET(connfd, &master); // add to master set if (connfd > fdmax) { // keep track of the max fdmax = connfd; } printf("new connection from %s on " "socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), connfd); } } else { // handle data from a client auto found = connections.find(i); if (found == connections.end()) { connections[i] = new SocketConnection(i); } SocketConnection *connection = connections[i]; try { int rcvd; rcvd = connection->read(request_buffer, REQUEST_BUFFER_SIZE); if (rcvd < 0) // receive error { perror("recv() error"); throw std::exception(); } else if (rcvd == 0) { fprintf(stderr,"Client disconnected unexpectedly.\n"); throw std::exception(); } if (data_received(connection, request_buffer, rcvd)) { connections.erase(i); delete(connection); FD_CLR(i, &master); // remove from master set } } catch (std::exception &e) { std::cerr << "exception handling request: " << e.what() << std::endl; connections.erase(i); connection_closed(connection); delete(connection); FD_CLR(i, &master); // remove from master set } } } } } }