Esempio n. 1
0
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 );
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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
            		}
            	}
            }
        }
	}
}