void TWorker::work(int socket) { std::string request; std::string fileName; // setNonBlock(socket); if( readRequest(socket, request) ) { #if defined(DEBUG) std::cout << "\n\nReqest:\n" << request; #endif std::string answer; if( parseRequest(request, fileName) ) { std::string context; if( getContext(fileName, context) ) { answer = createHeader(200, context.size() ) + context; } else { answer = createHeader(404); } } else { answer = createHeader(500); } #if defined(DEBUG) std::cout << "\n\nAnswer:\n" << answer; #endif sendAnswer(socket, answer); } disconnect(socket); }
void ExtCommandsHandler::run() { while (1) { QStringList args; if (!readRequest(&args)) { qWarning ("failed to read request from shell extension: %s", formatErrorMessage().c_str()); break; } QString cmd = args.takeAt(0); QString resp; if (cmd == "list-repos") { resp = handleListRepos(args); } else if (cmd == "get-share-link") { handleGenShareLink(args); } else if (cmd == "get-file-status") { resp = handleGetFileStatus(args); } else { qWarning ("[ext] unknown request command: %s", cmd.toUtf8().data()); } if (!sendResponse(resp)) { qWarning ("failed to write response to shell extension: %s", formatErrorMessage().c_str()); break; } } qWarning ("An extension client is disconnected: GLE=%lu\n", GetLastError()); DisconnectNamedPipe(pipe_); CloseHandle(pipe_); }
void work(int sock) { if (readRequest(sock) > 0) writeResponse(sock); snooze(0,1000000); // sleep for 1 milisecond if (--timeout <= 0) done = 1; if (timeout%1000 == 0) debug("Socket %d has %ds before disconnect",sock,timeout/1000); if (done) closeSocket(sock); }
void ClientConnection::loop() { if (state == FREE_STATE) { return; } if (client.connected()) { switch(state) { case READ_HEADER_STATE: case READ_REQUEST_STATE: readRequest(); break; case WRITE_HEADER_STATE: case WRITE_RESPONSE_STATE: writeResponse(); break; } if (millis() - lastUse > INACTIVITY_TIMEOUT_MS) { Serial.printlnf("%d: inactivity timeout", clientId); client.stop(); clear(); } } else { Serial.printlnf("%d: client disconnected", clientId); client.stop(); clear(); } }
QT_USE_NAMESPACE Dialog::Dialog(QWidget *parent) : QDialog(parent) , transactionCount(0) , serialPortLabel(new QLabel(tr("Serial port:"))) , serialPortComboBox(new QComboBox()) , waitRequestLabel(new QLabel(tr("Wait request, msec:"))) , waitRequestSpinBox(new QSpinBox()) , responseLabel(new QLabel(tr("Response:"))) , responseLineEdit(new QLineEdit(tr("Hello, I'm Slave."))) , trafficLabel(new QLabel(tr("No traffic."))) , statusLabel(new QLabel(tr("Status: Not running."))) , runButton(new QPushButton(tr("Start"))) { waitRequestSpinBox->setRange(0, 10000); waitRequestSpinBox->setValue(20); foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) serialPortComboBox->addItem(info.portName()); QGridLayout *mainLayout = new QGridLayout; mainLayout->addWidget(serialPortLabel, 0, 0); mainLayout->addWidget(serialPortComboBox, 0, 1); mainLayout->addWidget(waitRequestLabel, 1, 0); mainLayout->addWidget(waitRequestSpinBox, 1, 1); mainLayout->addWidget(runButton, 0, 2, 2, 1); mainLayout->addWidget(responseLabel, 2, 0); mainLayout->addWidget(responseLineEdit, 2, 1, 1, 3); mainLayout->addWidget(trafficLabel, 3, 0, 1, 4); mainLayout->addWidget(statusLabel, 4, 0, 1, 5); setLayout(mainLayout); setWindowTitle(tr("Slave")); serialPortComboBox->setFocus(); timer.setSingleShot(true); connect(runButton, SIGNAL(clicked()), this, SLOT(startSlave())); connect(&serial, SIGNAL(readyRead()), this, SLOT(readRequest())); connect(&timer, SIGNAL(timeout()), this, SLOT(processTimeout())); connect(serialPortComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(activateRunButton())); connect(waitRequestSpinBox, SIGNAL(valueChanged(int)), this, SLOT(activateRunButton())); connect(responseLineEdit, SIGNAL(textChanged(QString)), this, SLOT(activateRunButton())); }
void service(int server_fd) { for(;;) { Message msg = readRequest(server_fd); if (strncmp(msg.type, PIPE, 4) == 0) { char client_pipe[BUF_LEN]; strncpy(client_pipe, msg.msg_buf, BUF_LEN); int client_fd = open(client_pipe, O_WRONLY); writeResponse(client_fd, OK, 2); } else { printf("Couldn't decipher message\n"); } } }
HTTPConnection::HTTPConnection(QTcpSocket* socket, HTTPManager* parentManager) : QObject(parentManager), _parentManager(parentManager), _socket(socket), _address(socket->peerAddress()) { // take over ownership of the socket _socket->setParent(this); // connect initial slots connect(socket, SIGNAL(readyRead()), SLOT(readRequest())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(deleteLater())); connect(socket, SIGNAL(disconnected()), SLOT(deleteLater())); }
void Manager::registerSocket() { ++clientsConnected; QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); reportStatus(); Q_EMIT message(tr("Client %1(%2) connected.") .arg(clientConnection->peerAddress().toString()) .arg(clientConnection->peerPort())); connect(clientConnection, SIGNAL(disconnected()), this, SLOT(clearSocket())); connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readRequest())); connect(clientConnection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError))); }
THttpSocket::THttpSocket(QObject *parent) : QTcpSocket(parent), lengthToRead(-1) { T_TRACEFUNC(""); do { sid = point.fetch_add(1); } while (!socketManager[sid].compareExchange(nullptr, this)); // store a socket tSystemDebug("THttpSocket sid:%d", sid); connect(this, SIGNAL(readyRead()), this, SLOT(readRequest())); connect(this, SIGNAL(requestWrite(const QByteArray&)), this, SLOT(writeRawData(const QByteArray&)), Qt::QueuedConnection); idleElapsed = std::time(nullptr); }
TInt CCTSYIntegrationTestSuiteStepBase::DoPauseL(const TDesC& aText, TTimeDuration aTimeout /* = ETimeMedium */) /** Performs a pause, usually to allow user to intervene in Manual tests @param aText - text for prompt @param aTimeout - @return KErrNone if user pressed a key */ { TInt ret = KErrNone; CConsoleBase* con = NULL; TRAPD(err, con = Console::NewL(_L("Interactive Test"), TSize(KConsFullScreen, KConsFullScreen))); INFO_PRINTF2(_L("Console status = %d"), err); TEST(err == KErrNone); CleanupStack::PushL(con); TConsoleReadRequestStatus readRequest(*con); //add to cleanup stack CleanupStack::PushL(readRequest); con->Printf(_L("%S (timeout %d secs) ..."), &aText, aTimeout / KOneSecond); con->Read(readRequest); ret = WaitForRequestWithTimeOut(readRequest, aTimeout); if (ret == KErrTimedOut) { WARN_PRINTF1(_L("[doPause] No keypress detected, timeout! Manual action may not have occurred.")); } if (readRequest.Int() == KRequestPending) { readRequest.Cancel(); } CleanupStack::PopAndDestroy(); // readRequest CleanupStack::PopAndDestroy(); // con return ret; }
void HTTPConnection::readRequest() { if (!_socket->canReadLine()) { return; } if (!_requestUrl.isEmpty()) { qDebug() << "Request URL was already set"; return; } // parse out the method and resource QByteArray line = _socket->readLine().trimmed(); if (line.startsWith("HEAD")) { _requestOperation = QNetworkAccessManager::HeadOperation; } else if (line.startsWith("GET")) { _requestOperation = QNetworkAccessManager::GetOperation; } else if (line.startsWith("PUT")) { _requestOperation = QNetworkAccessManager::PutOperation; } else if (line.startsWith("POST")) { _requestOperation = QNetworkAccessManager::PostOperation; } else if (line.startsWith("DELETE")) { _requestOperation = QNetworkAccessManager::DeleteOperation; } else { qWarning() << "Unrecognized HTTP operation." << _address << line; respond("400 Bad Request", "Unrecognized operation."); return; } int idx = line.indexOf(' ') + 1; _requestUrl.setUrl(line.mid(idx, line.lastIndexOf(' ') - idx)); // switch to reading the header _socket->disconnect(this, SLOT(readRequest())); connect(_socket, SIGNAL(readyRead()), SLOT(readHeaders())); // read any headers immediately available readHeaders(); }
void TActionThread::run() { QList<THttpRequest> reqs; QEventLoop eventLoop; httpSocket = new THttpSocket; if (!httpSocket->setSocketDescriptor(TActionContext::socketDesc)) { emitError(httpSocket->error()); goto socket_error; } TActionContext::socketDesc = 0; for (;;) { reqs = readRequest(httpSocket); tSystemDebug("HTTP request count: %d", reqs.count()); if (reqs.isEmpty()) break; for (QMutableListIterator<THttpRequest> it(reqs); it.hasNext(); ) { THttpRequest &req = it.next(); TActionContext::execute(req); httpSocket->flush(); // Flush socket TActionContext::release(); } if (!httpSocket->waitForReadyRead(5000)) break; } closeHttpSocket(); // disconnect // For cleanup while (eventLoop.processEvents()) {} socket_error: delete httpSocket; httpSocket = 0; }
/** Function which handles the server process management. The function polls the requests directory for new requests generated by the client processes. The server process management function requires max_restarts as a limitation for graceful degradation. */ int server(int max_restarts) { /**Directory pointer used to point to the directory location requests.*/ DIR *dirp; /**Storage variable for return variable for usleep function call.*/ int ret_val_usleep; /**Directory entry pointer.*/ struct dirent *dp; printf("Server Process has begun processing the requests...\n"); /**Check for Failure in generation of backup process.*/ if(backup(max_restarts)==EXIT_SUCCESS) { printf("successfully executed...\n"); } /**If backup process cannot be created. The parent process takes control.(Graceful Degradation)*/ else { fprintf(stderr, "Error:Backup cannot be created.\nParent server process PID:%d taking control.\n",getpid()); } while(1) { /**Open the requests directory.*/ dirp = opendir("./requests"); /**Condition to check if the opendir function has failed or not.*/ if(dirp==NULL) { fprintf(stderr, "Error:Open Directory function failed.\n"); /**Process returns and terminates with error.*/ return EXIT_FAILURE; } while(dirp) { /**Storage variable to generate the absolute path for the request file name.*/ char request_name[100]="requests/"; /** Condition to check if the readdir function has reached end of the directory or not. It is a condition to detect even failures for the readdir function calls. readdir() returns the directory entry pointer to the next directory file inside the given directory location. */ if ((dp = readdir(dirp)) != NULL) { /** Check if the request file name contains req_ as the substring in the file name. And if the type of the file is Regular file or not. */ if ((strstr(dp->d_name,"req_")!=NULL)&&(dp->d_type == DT_REG)) { /**Generating the absolute path of the request file name.*/ if(strcat(request_name,dp->d_name)==NULL) { fprintf(stderr, "Error:String Concatenation function failed.\n"); return EXIT_FAILURE; } /** Performing readRequest Call with requesting file name and failure chance. Condition checks if the readRequest call failed or not. */ if(readRequest(request_name)==EXIT_FAILURE) { fprintf(stderr, "Error:readRequest function failed.\n"); return EXIT_FAILURE; } /** Performing removeRequest Call with requesting file name. Condition checks if the removeRequest call failed or not. */ if(removeRequest(request_name)==EXIT_FAILURE) { fprintf(stderr, "Error:removeRequest function failed.\n"); return EXIT_FAILURE; } /**Sleeping the process for 500ms.*/ ret_val_usleep = usleep(500000); /**Failure in usleep call*/ if(ret_val_usleep<0) { fprintf(stderr, "Error:Usleep function failed.\n"); /**Process returns and terminates with error*/ return EXIT_FAILURE; } } } else { /**Directory end reached.*/ break; } } /**Close the requests directory. Check if the close operation was successful or not.*/ if(closedir(dirp)<0) { fprintf(stderr, "Error:Usleep function failed.\n"); /**Process returns and terminates with error*/ return EXIT_FAILURE; } } /**Process returns and terminates with success.*/ return EXIT_SUCCESS; }
void TActionContext::execute() { T_TRACEFUNC(""); THttpResponseHeader responseHeader; accessLogger.open(); try { if (!readRequest()) { return; } const THttpRequestHeader &hdr = httpReq->header(); // Access log accessLogger.setTimestamp(QDateTime::currentDateTime()); QByteArray firstLine = hdr.method() + ' ' + hdr.path(); firstLine += QString(" HTTP/%1.%2").arg(hdr.majorVersion()).arg(hdr.minorVersion()).toLatin1(); accessLogger.setRequest(firstLine); accessLogger.setRemoteHost( (Tf::app()->appSettings().value(LISTEN_PORT).toUInt() > 0) ? clientAddress().toString().toLatin1() : QByteArray("(unix)") ); tSystemDebug("method : %s", hdr.method().data()); tSystemDebug("path : %s", hdr.path().data()); Tf::HttpMethod method = httpReq->method(); QString path = THttpUtility::fromUrlEncoding(hdr.path().mid(0, hdr.path().indexOf('?'))); // Routing info exists? TRouting rt = TUrlRoute::instance().findRouting(method, path); tSystemDebug("Routing: controller:%s action:%s", rt.controller.data(), rt.action.data()); if (rt.isEmpty()) { // Default URL routing rt.params = path.split('/'); if (path.startsWith(QLatin1Char('/')) && !rt.params.isEmpty()) { rt.params.removeFirst(); // unuse first item } if (path.endsWith(QLatin1Char('/')) && !rt.params.isEmpty()) { rt.params.removeLast(); // unuse last item } // Direct view render mode? if (Tf::app()->appSettings().value(DIRECT_VIEW_RENDER_MODE).toBool()) { // Direct view setting rt.controller = "directcontroller"; rt.action = "show"; } else { if (!rt.params.value(0).isEmpty()) { rt.controller = rt.params.takeFirst().toLower().toLatin1() + "controller"; if (rt.controller == "applicationcontroller") { rt.controller.clear(); // Can not call 'ApplicationController' } // Default action: index rt.action = rt.params.value(0, QLatin1String("index")).toLatin1(); if (!rt.params.isEmpty()) { rt.params.takeFirst(); } } tSystemDebug("Active Controller : %s", rt.controller.data()); } } // Call controller method TDispatcher<TActionController> ctlrDispatcher(rt.controller); currController = ctlrDispatcher.object(); if (currController) { currController->setActionName(rt.action); // Session if (currController->sessionEnabled()) { TSession session; QByteArray sessionId = httpReq->cookie(TSession::sessionName()); if (!sessionId.isEmpty()) { // Finds a session session = TSessionManager::instance().findSession(sessionId); } currController->setSession(session); // Exports flash-variant currController->exportAllFlashVariants(); } // Verify authenticity token if (Tf::app()->appSettings().value(ENABLE_CSRF_PROTECTION_MODULE, true).toBool() && currController->csrfProtectionEnabled() && !currController->exceptionActionsOfCsrfProtection().contains(rt.action)) { if (method == Tf::Post || method == Tf::Put || method == Tf::Delete) { if (!currController->verifyRequest(*httpReq)) { throw SecurityException("Invalid authenticity token", __FILE__, __LINE__); } } } if (currController->sessionEnabled()) { if (currController->session().id().isEmpty() || Tf::app()->appSettings().value(AUTO_ID_REGENERATION).toBool()) { TSessionManager::instance().remove(currController->session().sessionId); // Removes the old session // Re-generate session ID currController->session().sessionId = TSessionManager::instance().generateId(); tSystemDebug("Re-generate session ID: %s", currController->session().sessionId.data()); } // Sets CSRF protection informaion TActionController::setCsrfProtectionInto(currController->session()); } // Database Transaction transactions.setEnabled(currController->transactionEnabled()); // Do filters if (currController->preFilter()) { // Dispathes bool dispatched = ctlrDispatcher.invoke(rt.action, rt.params); if (dispatched) { autoRemoveFiles << currController->autoRemoveFiles; // Adds auto-remove files // Post fileter currController->postFilter(); if (currController->rollbackRequested()) { rollbackTransactions(); } else { // Commits a transaction to the database commitTransactions(); } // Session store if (currController->sessionEnabled()) { bool stored = TSessionManager::instance().store(currController->session()); if (stored) { QDateTime expire; if (TSessionManager::sessionLifeTime() > 0) { expire = QDateTime::currentDateTime().addSecs(TSessionManager::sessionLifeTime()); } // Sets the path in the session cookie QString cookiePath = Tf::app()->appSettings().value(SESSION_COOKIE_PATH).toString(); currController->addCookie(TSession::sessionName(), currController->session().id(), expire, cookiePath); } } } } // Sets charset to the content-type QByteArray ctype = currController->response.header().contentType().toLower(); if (ctype.startsWith("text") && !ctype.contains("charset")) { ctype += "; charset="; ctype += Tf::app()->codecForHttpOutput()->name(); currController->response.header().setContentType(ctype); } // Sets the default status code of HTTP response accessLogger.setStatusCode( (!currController->response.isBodyNull()) ? currController->statusCode() : Tf::InternalServerError ); currController->response.header().setStatusLine(accessLogger.statusCode(), THttpUtility::getResponseReasonPhrase(accessLogger.statusCode())); // Writes a response and access log int bytes = writeResponse(currController->response.header(), currController->response.bodyIODevice(), currController->response.bodyLength()); accessLogger.setResponseBytes(bytes); // Session GC TSessionManager::instance().collectGarbage(); } else { accessLogger.setStatusCode( Tf::BadRequest ); if (method == Tf::Get) { // GET Method path.remove(0, 1); QFile reqPath(Tf::app()->publicPath() + path); QFileInfo fi(reqPath); if (fi.isFile() && fi.isReadable()) { // Check "If-Modified-Since" header for caching bool sendfile = true; QByteArray ifModifiedSince = hdr.rawHeader("If-Modified-Since"); if (!ifModifiedSince.isEmpty()) { QDateTime dt = THttpUtility::fromHttpDateTimeString(ifModifiedSince); sendfile = (!dt.isValid() || dt != fi.lastModified()); } if (sendfile) { // Sends a request file responseHeader.setRawHeader("Last-Modified", THttpUtility::toHttpDateTimeString(fi.lastModified())); QByteArray type = Tf::app()->internetMediaType(fi.suffix()); int bytes = writeResponse(Tf::OK, responseHeader, type, &reqPath, reqPath.size()); accessLogger.setResponseBytes( bytes ); } else { // Not send the data int bytes = writeResponse(Tf::NotModified, responseHeader); accessLogger.setResponseBytes( bytes ); } } else { int bytes = writeResponse(Tf::NotFound, responseHeader); accessLogger.setResponseBytes( bytes ); } accessLogger.setStatusCode( responseHeader.statusCode() ); } else if (method == Tf::Post) { // file upload? } else { // HEAD, DELETE, ... } } } catch (ClientErrorException &e) { tWarn("Caught ClientErrorException: status code:%d", e.statusCode()); int bytes = writeResponse(e.statusCode(), responseHeader); accessLogger.setResponseBytes( bytes ); accessLogger.setStatusCode( e.statusCode() ); } catch (SqlException &e) { tError("Caught SqlException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); tSystemError("Caught SqlException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); closeHttpSocket(); } catch (KvsException &e) { tError("Caught KvsException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); tSystemError("Caught KvsException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); closeHttpSocket(); } catch (SecurityException &e) { tError("Caught SecurityException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); tSystemError("Caught SecurityException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); closeHttpSocket(); } catch (RuntimeException &e) { tError("Caught RuntimeException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); tSystemError("Caught RuntimeException: %s [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber()); closeHttpSocket(); } catch (...) { tError("Caught Exception"); tSystemError("Caught Exception"); closeHttpSocket(); } // Push to the pool TActionContext::releaseSqlDatabases(); TActionContext::releaseKvsDatabases(); TActionContext::accessLogger.write(); // Writes access log releaseHttpSocket(); }
int main(int argc, char* argv[]) { Config config; int socket; int returnStatus = 0; struct sockaddr_in tcpServer; /* server is running */ server_running = 1; server_pid = getpid(); /* no requests yet! */ total_requests = 0; /* make sure we've got a config file */ if(argc < 2) { fprintf(stderr, "Usage: %s <config_file>\n", argv[0]); exit(1); } /* load the config file, abort on error */ if(load_config(&config, argv[1]) < 0) { fprintf(stderr, "Error parsing config file %s\n", argv[1]); exit(1); } /* create a UDP socket or die */ if((socket = e_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { exit(1); } /* allow re-use of socket addresses to avoid 'already bound' problems */ int v = 1; returnStatus = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)); if(returnStatus < 0) { perror("Setting socket option failed"); exit(1); } /* set up the TCP server */ tcpServer.sin_family = AF_INET; tcpServer.sin_port = htons(config.port); tcpServer.sin_addr.s_addr = INADDR_ANY; /* bind socket to the server */ returnStatus = bind(socket, (struct sockaddr*)&tcpServer, sizeof(tcpServer)); if(returnStatus < 0) { perror("Bind Failed"); if(close(socket) < 0) { perror("Error closing socket"); } exit(1); } /* allow a given signal to terminate server */ struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = sigshutdown_handler; sigaction(config.shutdown_signal, &act, 0); /* open log file if enabled */ if(config.logging) { logfile = fopen_or_die(config.logfile, "w"); } /* run indefinitely */ int connect_fd; if(config.logging) { slog(logfile, "Server started\n"); slog(logfile, "Listening on port %d\n", config.port); } /* listen for connections */ returnStatus = listen(socket, BACK_LOG); if(returnStatus < 0) { perror("Error listening for connection"); } while(server_running) { /* accept an incoming connection from queue */ if((connect_fd = accept(socket, NULL, NULL)) < 0) { /* may have been interrupted, safe to try again */ if(errno == EINTR || errno == EAGAIN) { continue; } else { perror("Unable to accept connection"); exit(EXIT_FAILURE); } } else { /* read in an entire HTTP request */ FILE* record_file = NULL; if(config.recording) { record_file = fopen_or_die(config.recordfile, "w"); } char* request = readRequest(connect_fd, record_file); /* ensure is a valid request i.e is a GET and hostname matches */ char* file_path = malloc_or_die(BUFFER_LEN); if(parseRequest(connect_fd, request, file_path, &config)) { ReplyParams r; r.connect_fd = connect_fd; strncpy(r.file_path, file_path, BUFFER_LEN); r.c = &config; r.logfile = logfile; sendHttpReply(&r); } /* successfully handled a request, count it */ total_requests++; /* shutdown & close client connection */ close(connect_fd); } } if(close(socket) < 0) { perror("Error closing socket"); } /* cleanup & exit */ if(config.logging) { slog(logfile, "Terminating server\n"); fclose(logfile); } return 0; }
void CNearbySession::doSession(SOCKET sessionSocket, SOCKET cancelSocket) { this->sessionSocket = sessionSocket; std::cout << "CNearby::startup - accepted connection!" << std::endl; uint32_t sequence = 1; fd_set readFds; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; std::string remoteDevice, remoteEndpoint; SOCKET selectSocket = std::max<SOCKET>(sessionSocket, std::max<SOCKET>(queueReadySocket, cancelSocket)) + 1; std::vector<uint8_t> buffer; buffer.reserve(chunkSize*2); bool sessionLoop = true; while(sessionLoop) { FD_ZERO(&readFds); FD_SET(sessionSocket, &readFds); FD_SET(queueReadySocket, &readFds); if (cancelSocket != SOCKET_ERROR) { FD_SET(cancelSocket, &readFds); } tv.tv_sec = 5; tv.tv_usec = 0; if(int activity = select(selectSocket, &readFds, nullptr, nullptr, &tv)) { //check for read if (FD_ISSET(cancelSocket, &readFds)) { //data on cancelSocket means we should quit std::cerr << "CNearby::doSession - sessionSocket error set!" << std::endl; break; } if (FD_ISSET(queueReadySocket, &readFds)) { //data on messageQueue means we should send it std::cerr << "CNearby::doSession - messageQueue notification set!" << std::endl; NotificationSocket::Clear(queueReadySocket); doWriteQueue(sessionSocket, sequence); } if (FD_ISSET(sessionSocket, &readFds)) { sessionLoop = readRequest(sessionSocket, buffer, sequence, remoteDevice, remoteEndpoint); } } else { std::cerr << "CNearby::doSession - send Ping!" << std::endl; CNearbyMessage message; sendAnswer(sessionSocket, message.buildPing(sequence)); } } closesocket(sessionSocket); this->sessionSocket = SOCKET_ERROR; std::cout << "CNearby::doSession - complete!" << std::endl; }
/** *INICIO DO PROGRAMA PRINCIPAL */ int main (int argc, char **argv) { /* Os sockets. Um que será o socket que vai escutar pelas conexões * e o outro que vai ser o socket específico de cada conexão */ int listenfd, connfd; /* Informações sobre o socket (endereço e porta) ficam nesta struct */ struct sockaddr_in servaddr; /* Retorno da função fork para saber quem é o processo filho e quem * é o processo pai */ pid_t childpid; /* Armazena linhas recebidas do cliente */ char recvline[MAXLINE + 1]; /* Armazena o tamanho da string lida do cliente */ ssize_t n; if (argc != 2) { fprintf(stderr,"Uso: %s <Porta>\n",argv[0]); fprintf(stderr,"Vai rodar um servidor HTTP <Porta> TCP\n"); exit(1); } /* Criação de um socket. Eh como se fosse um descritor de arquivo. Eh * possivel fazer operacoes como read, write e close. Neste * caso o socket criado eh um socket IPv4 (por causa do AF_INET), * que vai usar TCP (por causa do SOCK_STREAM), já que o HTTP * funciona sobre TCP, e será usado para uma aplicação convencional sobre * a Internet (por causa do número 0) */ if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket :(\n"); exit(2); } /* Agora é necessário informar os endereços associados a este * socket. É necessário informar o endereço / interface e a porta, * pois mais adiante o socket ficará esperando conexões nesta porta * e neste(s) endereços. Para isso é necessário preencher a struct * servaddr. É necessário colocar lá o tipo de socket (No nosso * caso AF_INET porque é IPv4), em qual endereço / interface serão * esperadas conexões (Neste caso em qualquer uma -- INADDR_ANY) e * qual a porta. Neste caso será a porta que foi passada como * argumento no shell (atoi(argv[1])) */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(atoi(argv[1])); if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("bind :(\n"); exit(3); } /* Como este código é o código de um servidor, o socket será um * socket passivo. Para isto é necessário chamar a função listen * que define que este é um socket de servidor que ficará esperando * por conexões nos endereços definidos na função bind. */ if (listen(listenfd, LISTENQ) == -1) { perror("listen :(\n"); exit(4); } system("clear"); printf("[Servidor no ar. Aguardando conexoes na porta %s]\n",argv[1]); printf("[Para finalizar, pressione CTRL+c ou rode um kill ou killall]\n"); /* O servidor no final das contas é um loop infinito de espera por * conexões e processamento de cada uma individualmente */ for (;;) { /* O socket inicial que foi criado é o socket que vai aguardar * pela conexão na porta especificada. Mas pode ser que existam * diversos clientes conectando no servidor. Por isso deve-se * utilizar a função accept. Esta função vai retirar uma conexão * da fila de conexões que foram aceitas no socket listenfd e * vai criar um socket específico para esta conexão. O descritor * deste novo socket é o retorno da função accept. */ if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1 ) { perror("accept :(\n"); exit(5); } /* Agora o servidor precisa tratar este cliente de forma * separada. Para isto é criado um processo filho usando a * função fork. O processo vai ser uma cópia deste. Depois da * função fork, os dois processos (pai e filho) estarão no mesmo * ponto do código, mas cada um terá um PID diferente. Assim é * possível diferenciar o que cada processo terá que fazer. O * filho tem que processar a requisição do cliente. O pai tem * que voltar no loop para continuar aceitando novas conexões */ /* Se o retorno da função fork for zero, é porque está no * processo filho. */ if ( (childpid = fork()) == 0) { /**** PROCESSO FILHO ****/ printf("[Uma conexao aberta]\n"); /* Já que está no processo filho, não precisa mais do socket * listenfd. Só o processo pai precisa deste socket. */ close(listenfd); /* Agora pode ler do socket e escrever no socket. Isto tem * que ser feito em sincronia com o cliente. Não faz sentido * ler sem ter o que ler. Ou seja, neste caso está sendo * considerado que o cliente vai enviar algo para o servidor. * O servidor vai processar o que tiver sido enviado e vai * enviar uma resposta para o cliente (Que precisará estar * esperando por esta resposta) */ /* ========================================================= */ /* ========================================================= */ /* EP1 INÍCIO */ /* ========================================================= */ /* ========================================================= */ /* TODO: É esta parte do código que terá que ser modificada * para que este servidor consiga interpretar comandos HTTP */ /* Definindo o cliente */ Host cliente; cliente.destino = servaddr; cliente.socket = connfd; /* Ler a requisição do cliente*/ Request client_request = readRequest(cliente); /* Mostrar na tela as requisições dos clientes */ printf("*********************************************************************"); printf("\n [Metodo requisitado]: %s \n", client_request.metodo); printf("\n [Recurso solicitado]: %s \n", client_request.recurso); printf("\n [Protocolo]: %s \n", client_request.protocolo); /* checar a Request do client */ CR_returns returns = checkRequest(cliente, client_request); /* enviar resposta da requisição para o cliente */ if (strcmp(client_request.metodo,"GET")==0) { sendGETRequest(cliente, returns); } else if (strcmp(client_request.metodo,"POST")==0) { sendPOSTRequest(cliente, returns,client_request); } /* ========================================================= */ /* ========================================================= */ /* EP1 FIM */ /* ========================================================= */ /* ========================================================= */ /* Após ter feito toda a troca de informação com o cliente, * pode finalizar o processo filho */ printf("[Uma conexao fechada]\n"); exit(0); } /**** PROCESSO PAI ****/ /* Se for o pai, a única coisa a ser feita é fechar o socket * connfd (ele é o socket do cliente específico que será tratado * pelo processo filho) */ close(connfd); } exit(0); }
THttpSocket::THttpSocket(QObject *parent) : QTcpSocket(parent), lengthToRead(-1), lastProcessed(QDateTime::currentDateTime()) { T_TRACEFUNC(""); connect(this, SIGNAL(readyRead()), this, SLOT(readRequest())); }