//---------------------------------------------------------------------------------- void tst_QTcpServer::waitForConnectionTest() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("Localhost servers don't work well with SOCKS5", SkipAll); } } QTcpSocket findLocalIpSocket; findLocalIpSocket.connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(findLocalIpSocket.waitForConnected(5000)); QTcpServer server; bool timeout = false; QVERIFY(server.listen(findLocalIpSocket.localAddress())); QVERIFY(!server.waitForNewConnection(1000, &timeout)); QCOMPARE(server.serverError(), QAbstractSocket::SocketTimeoutError); QVERIFY(timeout); ThreadConnector connector(findLocalIpSocket.localAddress(), server.serverPort()); connector.start(); #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QVERIFY(server.waitForNewConnection(9000, &timeout)); #else QVERIFY(server.waitForNewConnection(3000, &timeout)); #endif QVERIFY(!timeout); }
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTcpServer server; if (!server.listen(QHostAddress::LocalHost, 49199)) { qDebug("Failed to listen: %s", server.errorString().toLatin1().constData()); return 1; } #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QFile file(QLatin1String("/test_signal.txt")); file.open(QIODevice::WriteOnly); file.write("Listening\n"); file.flush(); file.close(); #else printf("Listening\n"); fflush(stdout); #endif server.waitForNewConnection(5000); qFatal("Crash"); return 0; }
//---------------------------------------------------------------------------------- void tst_QTcpServer::ipv6Server() { #if defined(Q_OS_SYMBIAN) QSKIP("Symbian: IPv6 is not yet supported", SkipAll); #endif //### need to enter the event loop for the server to get the connection ?? ( windows) QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 8944)) { QVERIFY(server.serverError() == QAbstractSocket::UnsupportedSocketOperationError); return; } QVERIFY(server.serverPort() == 8944); QVERIFY(server.serverAddress() == QHostAddress::LocalHostIPv6); QTcpSocket client; client.connectToHost("::1", 8944); QVERIFY(client.waitForConnected(5000)); QVERIFY(server.waitForNewConnection()); QVERIFY(server.hasPendingConnections()); QTcpSocket *serverSocket = 0; QVERIFY((serverSocket = server.nextPendingConnection())); }
// test only for posix void tst_QSocketNotifier::posixSockets() { QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_addr.s_addr = htonl(0x7f000001); addr.sin_family = AF_INET; addr.sin_port = htons(server.serverPort()); qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); QVERIFY(server.waitForNewConnection(5000)); QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); { QSocketNotifier rn(posixSocket, QSocketNotifier::Read); connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy readSpy(&rn, SIGNAL(activated(int))); QVERIFY(readSpy.isValid()); // No write notifier, some systems trigger write notification on socket creation, but not all QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy errorSpy(&en, SIGNAL(activated(int))); QVERIFY(errorSpy.isValid()); passive->write("hello",6); passive->waitForBytesWritten(5000); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); char buffer[100]; int r = qt_safe_read(posixSocket, buffer, 100); QCOMPARE(r, 6); QCOMPARE(buffer, "hello"); QSocketNotifier wn(posixSocket, QSocketNotifier::Write); connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); QVERIFY(writeSpy.isValid()); qt_safe_write(posixSocket, "goodbye", 8); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(writeSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); // Write notifier may have fired before the read notifier inside // QTcpSocket, give QTcpSocket a chance to see the incoming data passive->waitForReadyRead(100); QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); } qt_safe_close(posixSocket); }
bool DesignerExternalEditor::startEditor(const QString &fileName, QString *errorMessage) { EditorLaunchData data; // Find the editor binary if (!getEditorLaunchData(fileName, &QtSupport::BaseQtVersion::designerCommand, QLatin1String(designerBinaryC), QStringList(), false, &data, errorMessage)) { return false; } // Known one? const ProcessCache::iterator it = m_processCache.find(data.binary); if (it != m_processCache.end()) { // Process is known, write to its socket to cause it to open the file if (debug) qDebug() << Q_FUNC_INFO << "\nWriting to socket:" << data.binary << fileName; QTcpSocket *socket = it.value(); if (!socket->write(fileName.toUtf8() + '\n')) { *errorMessage = tr("Qt Designer is not responding (%1).").arg(socket->errorString()); return false; } return true; } // No process yet. Create socket & launch the process QTcpServer server; if (!server.listen(QHostAddress::LocalHost)) { *errorMessage = tr("Unable to create server socket: %1").arg(server.errorString()); return false; } const quint16 port = server.serverPort(); if (debug) qDebug() << Q_FUNC_INFO << "\nLaunching server:" << port << data.binary << fileName; // Start first one with file and socket as '-client port file' // Wait for the socket listening data.arguments.push_front(QString::number(port)); data.arguments.push_front(QLatin1String("-client")); if (!startEditorProcess(data, errorMessage)) return false; // Set up signal mapper to track process termination via socket if (!m_terminationMapper) { m_terminationMapper = new QSignalMapper(this); connect(m_terminationMapper, SIGNAL(mapped(QString)), this, SLOT(processTerminated(QString))); } // Insert into cache if socket is created, else try again next time if (server.waitForNewConnection(3000)) { QTcpSocket *socket = server.nextPendingConnection(); socket->setParent(this); m_processCache.insert(data.binary, socket); m_terminationMapper->setMapping(socket, data.binary); connect(socket, SIGNAL(disconnected()), m_terminationMapper, SLOT(map())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), m_terminationMapper, SLOT(map())); } return true; }
void tst_QSocketNotifier::posixSockets() { #ifndef Q_OS_UNIX QSKIP("test only for posix", SkipAll); #else QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_addr.s_addr = htonl(0x7f000001); addr.sin_family = AF_INET; addr.sin_port = htons(server.serverPort()); qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); QVERIFY(server.waitForNewConnection(5000)); QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); { QSocketNotifier rn(posixSocket, QSocketNotifier::Read); connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy readSpy(&rn, SIGNAL(activated(int))); QSocketNotifier wn(posixSocket, QSocketNotifier::Write); connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); QSignalSpy errorSpy(&en, SIGNAL(activated(int))); passive->write("hello",6); passive->waitForBytesWritten(5000); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); writeSpy.clear(); //depending on OS, write notifier triggers on creation or not. QCOMPARE(errorSpy.count(), 0); char buffer[100]; qt_safe_read(posixSocket, buffer, 100); QCOMPARE(buffer, "hello"); qt_safe_write(posixSocket, "goodbye", 8); QTestEventLoop::instance().enterLoop(3); QCOMPARE(readSpy.count(), 1); QCOMPARE(writeSpy.count(), 1); QCOMPARE(errorSpy.count(), 0); QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); } qt_safe_close(posixSocket); #endif }
//---------------------------------------------------------------------------------- void tst_QTcpServer::ipv4LoopbackPerformanceTest() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); QVERIFY(server.isListening()); QTcpSocket clientA; clientA.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(clientA.waitForConnected(5000)); QVERIFY(clientA.state() == QAbstractSocket::ConnectedState); QVERIFY(server.waitForNewConnection()); QTcpSocket *clientB = server.nextPendingConnection(); QVERIFY(clientB); QByteArray buffer(16384, '@'); QTime stopWatch; stopWatch.start(); qlonglong totalWritten = 0; while (stopWatch.elapsed() < 5000) { QVERIFY(clientA.write(buffer.data(), buffer.size()) > 0); clientA.flush(); totalWritten += buffer.size(); while (clientB->waitForReadyRead(100)) { if (clientB->bytesAvailable() == 16384) break; } clientB->read(buffer.data(), buffer.size()); clientB->write(buffer.data(), buffer.size()); clientB->flush(); totalWritten += buffer.size(); while (clientA.waitForReadyRead(100)) { if (clientA.bytesAvailable() == 16384) break; } clientA.read(buffer.data(), buffer.size()); } qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s", server.serverAddress().toString().toLatin1().constData(), totalWritten / (1024.0 * 1024.0), stopWatch.elapsed() / 1000.0, (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024)); delete clientB; }
//---------------------------------------------------------------------------------- void tst_QTcpServer::maxPendingConnections() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 only 1 connection is allowed ever", SkipAll); } } //### sees to fail sometimes ... a timing issue with the test on windows QTcpServer server; server.setMaxPendingConnections(2); QTcpSocket socket1; QTcpSocket socket2; QTcpSocket socket3; QVERIFY(server.listen()); socket1.connectToHost(QHostAddress::LocalHost, server.serverPort()); socket2.connectToHost(QHostAddress::LocalHost, server.serverPort()); socket3.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); QVERIFY(!server.hasPendingConnections()); QCOMPARE(server.nextPendingConnection(), (QTcpSocket*)0); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QVERIFY(server.nextPendingConnection()); }
//---------------------------------------------------------------------------------- void tst_QTcpServer::ipv4PerformanceTest() { QTcpSocket probeSocket; probeSocket.connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(probeSocket.waitForConnected(5000)); QTcpServer server; QVERIFY(server.listen(probeSocket.localAddress(), 0)); QTcpSocket clientA; clientA.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(clientA.waitForConnected(5000)); QVERIFY(server.waitForNewConnection(5000)); QTcpSocket *clientB = server.nextPendingConnection(); QVERIFY(clientB); QByteArray buffer(16384, '@'); QTime stopWatch; stopWatch.start(); qlonglong totalWritten = 0; while (stopWatch.elapsed() < 5000) { qlonglong writtenA = clientA.write(buffer.data(), buffer.size()); clientA.flush(); totalWritten += buffer.size(); while (clientB->waitForReadyRead(100)) { if (clientB->bytesAvailable() == writtenA) break; } clientB->read(buffer.data(), buffer.size()); qlonglong writtenB = clientB->write(buffer.data(), buffer.size()); clientB->flush(); totalWritten += buffer.size(); while (clientA.waitForReadyRead(100)) { if (clientA.bytesAvailable() == writtenB) break; } clientA.read(buffer.data(), buffer.size()); } qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s", probeSocket.localAddress().toString().toLatin1().constData(), totalWritten / (1024.0 * 1024.0), stopWatch.elapsed() / 1000.0, (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024)); delete clientB; }
//---------------------------------------------------------------------------------- void tst_QTcpServer::clientServerLoop() { QTcpServer server; QSignalSpy spy(&server, SIGNAL(newConnection())); QVERIFY(!server.isListening()); QVERIFY(!server.hasPendingConnections()); QVERIFY(server.listen(QHostAddress::Any, 11423)); QVERIFY(server.isListening()); QTcpSocket client; QHostAddress serverAddress = QHostAddress::LocalHost; if (!(server.serverAddress() == QHostAddress::Any)) serverAddress = server.serverAddress(); client.connectToHost(serverAddress, server.serverPort()); QVERIFY(client.waitForConnected(5000)); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.hasPendingConnections()); QCOMPARE(spy.count(), 1); QTcpSocket *serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket != 0); QVERIFY(serverSocket->write("Greetings, client!\n", 19) == 19); serverSocket->flush(); QVERIFY(client.waitForReadyRead(5000)); QByteArray arr = client.readAll(); QCOMPARE(arr.constData(), "Greetings, client!\n"); QVERIFY(client.write("Well, hello to you!\n", 20) == 20); client.flush(); QVERIFY(serverSocket->waitForReadyRead(5000)); arr = serverSocket->readAll(); QCOMPARE(arr.constData(), "Well, hello to you!\n"); }
// Test buffered socket being properly closed on remote disconnect void tst_QAbstractSocket::serverDisconnectWithBuffered() { QTcpServer tcpServer; #ifndef QT_NO_SSL QSslSocket testSocket; #else QTcpSocket testSocket; #endif QVERIFY(tcpServer.listen(QHostAddress::LocalHost)); testSocket.connectToHost(tcpServer.serverAddress(), tcpServer.serverPort()); // Accept connection on server side QVERIFY(tcpServer.waitForNewConnection(5000)); QTcpSocket *newConnection = tcpServer.nextPendingConnection(); // Send one char and drop link QVERIFY(newConnection != NULL); QVERIFY(newConnection->putChar(0)); QVERIFY(newConnection->flush()); delete newConnection; QVERIFY(testSocket.waitForConnected(5000)); // ready for write QVERIFY(testSocket.state() == QAbstractSocket::ConnectedState); QSignalSpy spyStateChanged(&testSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState))); QSignalSpy spyDisconnected(&testSocket, SIGNAL(disconnected())); QVERIFY(testSocket.waitForReadyRead(5000)); // have one char already in internal buffer char buf[128]; QCOMPARE(testSocket.read(buf, sizeof(buf)), Q_INT64_C(1)); if (testSocket.state() != QAbstractSocket::UnconnectedState) { QVERIFY(testSocket.waitForDisconnected(5000)); QVERIFY(testSocket.state() == QAbstractSocket::UnconnectedState); } // Test signal emitting QVERIFY(spyDisconnected.count() == 1); QVERIFY(spyStateChanged.count() > 0); QVERIFY(qvariant_cast<QAbstractSocket::SocketState>(spyStateChanged.last().first()) == QAbstractSocket::UnconnectedState); }
TEST_F(SocketTest, socketReceivesIncomingDataUsingQDataStream_Test) { QTcpServer server; server.listen(HOST, PORT); _socket->connectToHost(HOST, PORT); bool timedOut = false; EXPECT_TRUE(server.waitForNewConnection(TCP_TIMEOUT_MS, &timedOut)); EXPECT_FALSE(timedOut); QTcpSocket* serverSocket = server.nextPendingConnection(); EXPECT_THAT(serverSocket, NotNull()); flushEvents(); EXPECT_EQ(QAbstractSocket::ConnectedState, _socket->state()); EXPECT_EQ(QAbstractSocket::ConnectedState, serverSocket->state()); QDataStream out(serverSocket); out << static_cast<quint32>(42); EXPECT_TRUE(serverSocket->waitForBytesWritten(TCP_TIMEOUT_MS)); EXPECT_TRUE(_socket->ioDevice()->waitForReadyRead(TCP_TIMEOUT_MS)); quint32 i = 0; QDataStream in(_socket->ioDevice()); in >> i; EXPECT_EQ(static_cast<quint32>(42), i); }
void tst_QSocketNotifier::unexpectedDisconnection() { /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot invoked by one of the socket notifiers empties both sockets, the other notifier will also emit activated(). This results in unexpected disconnection in QAbstractSocket. The use case is that somebody calls one of the waitFor... functions in a QSocketNotifier activated slot, and the waitFor... functions do local selects that can empty both stdin and stderr while waiting for fex bytes to be written. */ QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); NATIVESOCKETENGINE readEnd1; readEnd1.initialize(QAbstractSocket::TcpSocket); readEnd1.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(readEnd1.waitForWrite()); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); QVERIFY(server.waitForNewConnection()); QTcpSocket *writeEnd1 = server.nextPendingConnection(); QVERIFY(writeEnd1 != 0); NATIVESOCKETENGINE readEnd2; readEnd2.initialize(QAbstractSocket::TcpSocket); readEnd2.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(readEnd2.waitForWrite()); QVERIFY(readEnd2.state() == QAbstractSocket::ConnectedState); QVERIFY(server.waitForNewConnection()); QTcpSocket *writeEnd2 = server.nextPendingConnection(); QVERIFY(writeEnd2 != 0); writeEnd1->write("1", 1); writeEnd2->write("2", 1); writeEnd1->waitForBytesWritten(); writeEnd2->waitForBytesWritten(); writeEnd1->flush(); writeEnd2->flush(); UnexpectedDisconnectTester tester(&readEnd1, &readEnd2); QTimer timer; timer.setSingleShot(true); timer.start(30000); do { // we have to wait until sequence value changes // as any event can make us jump out processing QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); QVERIFY(timer.isActive()); //escape if test would hang } while(tester.sequence <= 0); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); QVERIFY(readEnd2.state() == QAbstractSocket::ConnectedState); QCOMPARE(tester.sequence, 2); readEnd1.close(); readEnd2.close(); writeEnd1->close(); writeEnd2->close(); server.close(); }
//Thread run void ViewerHandler::run() { WDEF; pSocket = 0; int i; //Request and voiceClient creation and initialization (using ViewerHandler::requestQueue) //TalkingThread tt(this->request); this->tt = new TalkingThread(*this); this->connection = new Connection(*this, *(this->tt)); this->request = new Request(*this, requestQueue, *connection); //VoiceClient deals with messages originated in the client VoiceClient voiceClient(requestQueue); voiceClient.start(); WDEBUG1("ViewerHandler: whisper started"); //Server listening to localhost:44125 QTcpServer server; server.listen(QHostAddress::LocalHost, (quint16)44125); WDEBUG3("ViewerHandler: waiting for connection to %s:%d", "127.0.0.1", 44125); //Timeout if(!server.waitForNewConnection(10000)) WTHROW1("no connection found"); // Getting ViewerHandler::pSocket pSocket = server.nextPendingConnection(); if (!pSocket) WTHROW1("ViewerHandler: invalid socket - terminating"); WDEBUG1("ViewerHandler: entering main loop"); initialized(); // Main request processing loop for(;;) { if (pSocket->bytesAvailable() > 0 || pSocket->waitForReadyRead(10000)) { WDEBUG1("ViewerHandler: reading data from buffer"); //Reads the whole buffer QString qsData = pSocket->readAll(); // TODO: it might be that this is not the only request in the string // -> the request should be handled properly if(qsData.contains("Connector.InitiateShutdown.1")) { WDEBUG1("ViewerHandler: Connector.InitiateShutdown.1 received - doing nothing"); //break; } //Splits the buffer in several requests QStringList& rlRequests = qsData.split("\n\n\n", QString::SkipEmptyParts); //Counts number of requests int count = rlRequests.size(); WDEBUG2("ViewerHandler: %d request(s) received", count); //For each request for (i=0; i<count; i++) { WDEBUG3("ViewerHandler: Sending request %d to be handled: \n%s\n", i, rlRequests[i].toAscii().data()); //handles it if(this->request->handle(rlRequests[i])) { WDEBUG1("ViewerHandler: error while handling request - next request"); continue; } } //If there're no requests received } else { //Checks if socket is still valid and disconnect if not WDEBUG2("Socket state: %d", (int) pSocket->state()); if(pSocket->state() != QAbstractSocket::ConnectedState) { WDEBUG1("Socket is no more connected - closing program"); WWRITE1 ("Socket no more connected - shutting down"); break; } } } WEND: WDEBUG1("ViewerHandler: sending quit to the main application"); qApp->quit(); while (!is_shutdown()) { //wait to receive shutdown from main thread WDEBUG1("ViewerHandler: waiting to receive shutdown"); QThread::msleep(1000); //vhSleep(1000); } WDEBUG1("ViewerHandler: shutdown received"); WDEBUG1("ViewerHandler: stopping VoiceClient..."); voiceClient.end(); voiceClient.wait(); WDEBUG1("Viewer Handler: VoiceClient has terminated"); //WDEBUG1("Stopping talkingThread..."); //if(this->tt->isRunning())this->tt->quit(); WDEBUG1("ViewerHandler: stopping TalkingThread..."); //voiceClient.end(); if(tt != 0) { tt->end(); tt->wait(); delete tt; tt=0; WDEBUG1("Viewer Handler: TalkingThread has terminated"); } WDEBUG1("ViewerHandler: finishing..."); if (pSocket){ pSocket->close(); WDEBUG2("ViewerHandler: pSocket status: %s", pSocket->state() == QAbstractSocket::UnconnectedState ? "Unconnected" : "Still Up"); pSocket = 0; } server.close(); WDEBUG2("ViewerHandler: server status: %s", server.isListening() ? "Listening" : "Shutdown"); return; }
//******************************************************************************* // Now that the first handshake is with TCP server, if the addreess/peer port of // the client is already on the thread pool, it means that a new connection is // requested (the old was desconnected). So we have to remove that thread from // the pool and then connect again. void UdpMasterListener::run() { mStopped = false; QHostAddress PeerAddress; // Object to store peer address int peer_udp_port; // Peer listening port int server_udp_port; // Server assigned udp port // Create and bind the TCP server // ------------------------------ QTcpServer TcpServer; if ( !TcpServer.listen(QHostAddress::Any, mServerPort) ) { std::cerr << "TCP Socket Server ERROR: " << TcpServer.errorString().toStdString() << endl; std::exit(1); } const int tcpTimeout = 5*1000; cout << "JackTrip MULTI-THREADED SERVER: TCP Server Listening in Port = " << TcpServer.serverPort() << endl; while ( !mStopped ) { cout << "JackTrip MULTI-THREADED SERVER: Waiting for client connections..." << endl; cout << "=======================================================" << endl; while ( !TcpServer.waitForNewConnection(1000) ) { if (mStopped) { return; } } // block until a new connection is received cout << "JackTrip MULTI-THREADED SERVER: Client Connection Received!" << endl; // Control loop to be able to exit if UDPs or TCPs error ocurr for (int dum = 0; dum<1; dum++) { QTcpSocket *clientConnection = TcpServer.nextPendingConnection(); if ( !clientConnection->waitForConnected(tcpTimeout) ) { std::cerr << clientConnection->errorString().toStdString() << endl; break; } PeerAddress = clientConnection->peerAddress(); cout << "JackTrip MULTI-THREADED SERVER: Client Connect Received from Address : " << PeerAddress.toString().toStdString() << endl; // Get UDP port from client // ------------------------ peer_udp_port = readClientUdpPort(clientConnection); if ( peer_udp_port == 0 ) { break; } cout << "JackTrip MULTI-THREADED SERVER: Client UDP Port is = " << peer_udp_port << endl; // Check is client is new or not // ----------------------------- // Check if Address is not already in the thread pool // check by comparing 32-bit addresses int id = isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port); // If the address is not new, we need to remove the client from the pool // before re-starting the connection if (id == -1) { int id_remove; id_remove = getPoolID(PeerAddress.toIPv4Address(), peer_udp_port); // stop the thread mJTWorkers->at(id_remove)->stopThread(); // block until the thread has been removed from the pool while ( isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port) == -1 ) { cout << "JackTrip MULTI-THREADED SERVER: Removing JackTripWorker from pool..." << endl; QThread::msleep(10); } // Get a new ID for this client //id = isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port); id = getPoolID(PeerAddress.toIPv4Address(), peer_udp_port); } // Assign server port and send it to Client server_udp_port = mBasePort+id; if ( sendUdpPort(clientConnection, server_udp_port) == 0 ) { clientConnection->close(); delete clientConnection; releaseThread(id); break; } // Close and Delete the socket // --------------------------- clientConnection->close(); delete clientConnection; cout << "JackTrip MULTI-THREADED SERVER: Client TCP Socket Closed!" << endl; // Spawn Thread to Pool // -------------------- // Register JackTripWorker with the master listener delete mJTWorkers->at(id); // just in case the Worker was previously created mJTWorkers->replace(id, new JackTripWorker(this)); // redirect port and spawn listener cout << "---> JackTrip MULTI-THREADED SERVER: Spawning Listener..." << endl; { QMutexLocker lock(&mMutex); mJTWorkers->at(id)->setJackTrip(id, mActiveAddress[id][0], server_udp_port, mActiveAddress[id][1], 1); /// \todo temp default to 1 channel } //send one thread to the pool cout << "---> JackTrip MULTI-THREADED SERVER: Starting Thread..." << endl; mThreadPool.start(mJTWorkers->at(id), QThread::TimeCriticalPriority); // wait until one is complete before another spawns while (mJTWorkers->at(id)->isSpawning()) { QThread::msleep(10); } //mTotalRunningThreads++; cout << "JackTrip MULTI-THREADED SERVER: Total Running Threads: " << mTotalRunningThreads << endl; cout << "===============================================================" << endl; QThread::msleep(100); } } /* // Create objects on the stack QUdpSocket MasterUdpSocket; QHostAddress PeerAddress; uint16_t peer_port; // Ougoing Peer port, in case they're not using the default // Bind the socket to the well known port bindUdpSocket(MasterUdpSocket, mServerPort); char buf[1]; cout << "Server Listening in UDP Port: " << mServerPort << endl; cout << "Waiting for client..." << endl; cout << "=======================================================" << endl; while ( !mStopped ) { //cout << "WAITING........................." << endl; while ( MasterUdpSocket.hasPendingDatagrams() ) { cout << "Received request from Client!" << endl; // Get Client IP Address and outgoing port from packet int rv = MasterUdpSocket.readDatagram(buf, 1, &PeerAddress, &peer_port); cout << "Peer Port in Server ==== " << peer_port << endl; if (rv < 0) { std::cerr << "ERROR: Bad UDP packet read..." << endl; } /// \todo Get number of channels in the client from header // check by comparing 32-bit addresses /// \todo Add the port number in the comparison cout << "peer_portpeer_portpeer_port === " << peer_port << endl; int id = isNewAddress(PeerAddress.toIPv4Address(), peer_port); //cout << "IDIDIDIDIDDID === " << id << endl; // If the address is new, create a new thread in the pool if (id >= 0) // old address is -1 { // redirect port and spawn listener sendToPoolPrototype(id); // wait until one is complete before another spawns while (mJTWorker->isSpawning()) { QThread::msleep(10); } mTotalRunningThreads++; cout << "Total Running Threads: " << mTotalRunningThreads << endl; cout << "=======================================================" << endl; } //cout << "ENDDDDDDDDDDDDDDDDDd === " << id << endl; } QThread::msleep(100); } */ }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); for(int i = 0 ; i < argc; i++){ qDebug() << argv[i] << endl; } if(argc >= 4) { //Getting first argument for application QString arg = argv[1]; //Sending mode if(arg == "send") { QTcpSocket *tcpSocket = new QTcpSocket(&a); QString port = argv[3]; tcpSocket->connectToHost(QHostAddress(argv[2]), port.toInt()); if(!tcpSocket->waitForConnected(10*1000)){ qDebug() << "Connection cant be established to host: " << argv[2] << ", at port: " << port << endl; }else{ //Sending mode = file QString type(argv[4]); if(type == "file") { QFile file(argv[5]); if(!file.open(QFile::ReadOnly)) { qDebug() << "Cannot open file" << endl; }else { qDebug() << "File size in bytes: " << file.size() << endl; int counter = 0; //Divide file into chunks of 300KB int chunkSize = 3 * 100000; while(counter < file.size()){ if(!file.seek(counter)){ qDebug() << "Cant seek the file to : " << counter << endl; }else{ QByteArray buffer = file.read(chunkSize); if(!buffer.isEmpty()){ int bytesWritten = tcpSocket->write(buffer); counter += bytesWritten; if(!tcpSocket->waitForBytesWritten(10*1000)) { qDebug() << "Error no bytes written" << tcpSocket->errorString() << endl; }else { qDebug() << "Bytes for writting: " << buffer.size() << ", " << bytesWritten << " bytes written. " << endl; } }else{ qDebug() << "0 bytes read from file, error: " << file.errorString() << endl; break; } } } } //Sending mode = string }else if(type == "string") { QByteArray data = argv[5]; int bytesWritten = tcpSocket->write(data); if(!tcpSocket->waitForBytesWritten(10000)) { qDebug() << "Error no bytes written" << tcpSocket->errorString() << endl; }else { qDebug() << bytesWritten << " bytes written. " << endl; } }else{ qDebug() << "Unknown sending format " << endl; } } tcpSocket->close(); delete tcpSocket; //Receiving mode }else if(arg == "receive") { QTcpServer *tcpServer = new QTcpServer(&a); QString port = argv[3]; if(!tcpServer->listen(QHostAddress(QString(argv[2])),port.toInt())){ qDebug() << "Error, could not start listening, " << tcpServer->serverError() << endl; }else{ QString fileName; QString destinationPath; //Getting name and path for the new file from user bool tryAgain = true; while(tryAgain){ qDebug() << "Enter filename for the new file (ex: picture.png) :"; QTextStream s(stdin); fileName = s.readLine(); qDebug() << "Enter destination path: "; QTextStream d(stdin); destinationPath = d.readLine(); if (!fileName.isEmpty() && !destinationPath.isEmpty()) { qDebug() << "The destination string: " << destinationPath + fileName; tryAgain = false; }else{ qDebug() << "You didnt enter filename, try again" << endl; } } bool working = true; while(working){ if(tcpServer->waitForNewConnection(10*1000)){ QTcpSocket *sock = tcpServer->nextPendingConnection(); sock->waitForReadyRead(10*1000); QByteArray receivedData; QFile file_handle(destinationPath + fileName); //While there is bytes available for receiving, receive them and write chunks of min 300KB to file while(sock->bytesAvailable()){ qDebug() << sock->bytesAvailable() << " bytes available for writting" << endl; receivedData.append(sock->readAll()); if(receivedData.size() > 3 * 100000){ if(!file_handle.isOpen()){ if(!file_handle.open(QFile::WriteOnly | QFile::Append | QFile::Text)){ qDebug() << "Could not open file for writing!" << endl; }else{ file_handle.write(receivedData); file_handle.flush(); file_handle.waitForBytesWritten(10*1000); qDebug() << "Written " << receivedData.size() << " to file. In KB = " << receivedData.size() / 1000 << endl; receivedData.clear(); } }else{ file_handle.write(receivedData); file_handle.flush(); file_handle.waitForBytesWritten(10*1000); qDebug() << "Written " << receivedData.size() << " to file. In KB = " << receivedData.size() / 1000 << endl; receivedData.clear(); } } sock->waitForReadyRead(10*1000); } file_handle.close(); //In case there is still data in buffer, but data is smaller than 300KB than append that remaining data to file also if(receivedData.size() != 0){ qDebug() << "Preparing to write remaining chunks of data" << endl; if(!file_handle.open(QFile::WriteOnly)){ qDebug() << "Could not open file for writing!" << endl; }else{ file_handle.write(receivedData); file_handle.flush(); file_handle.waitForBytesWritten(10*1000); qDebug() << "Written " << receivedData.size() << " to file. In MB = " << receivedData.size() / 1000000 << endl; receivedData.clear(); file_handle.close(); } } sock->close(); delete sock; // file_thread->deleteLater(); qDebug() << "Should i wait for other request? (y/n) default = yes" ; char answer; cin >> answer; if(answer == 'n'){ working = false; tcpServer->close(); delete tcpServer; } }else{ qDebug() << "No incoming connection" << endl; qDebug() << "Should i check for another request? (Yes / No)" ; char answer; cin >> answer; if(answer == 'n'){ working = false; tcpServer->close(); delete tcpServer; } } }