void tst_QTcpServer::proxyFactory() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QFETCH(QList<QNetworkProxy>, proxyList); QFETCH(QNetworkProxy, proxyUsed); QFETCH(bool, fails); MyProxyFactory *factory = new MyProxyFactory; factory->toReturn = proxyList; QNetworkProxyFactory::setApplicationProxyFactory(factory); QTcpServer server; bool listenResult = server.listen(); // Verify that the factory was called properly QCOMPARE(factory->callCount, 1); QCOMPARE(factory->lastQuery, QNetworkProxyQuery(0, QString(), QNetworkProxyQuery::TcpServer)); QCOMPARE(listenResult, !fails); QCOMPARE(server.errorString().isEmpty(), !fails); // note: the following test is not a hard failure. // Sometimes, error codes change for the better QTEST(int(server.serverError()), "expectedError"); }
//---------------------------------------------------------------------------------- void tst_QTcpServer::setSocketDescriptor() { QTcpServer server; QVERIFY(!server.setSocketDescriptor(42)); QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); #ifdef Q_OS_WIN // ensure winsock is started WSADATA wsaData; QVERIFY(WSAStartup(MAKEWORD(2,0), &wsaData) == NO_ERROR); #endif SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); QVERIFY(sock != INVALID_SOCKET); sockaddr_in sin; memset(&sin, 0, sizeof(sockaddr_in)); sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = 0x00000000; QVERIFY(::bind(sock, (sockaddr*)&sin, sizeof(sockaddr_in)) == 0); QVERIFY(::listen(sock, 10) == 0); QVERIFY(server.setSocketDescriptor(sock)); #ifdef Q_OS_WIN WSACleanup(); #endif }
//---------------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------------- 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())); }
//---------------------------------------------------------------------------------- void tst_QTcpServer::listenError() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QSKIP("With socks5 we can not make hard requirements on the address or port", SkipAll); } } QTcpServer server; QVERIFY(!server.listen(QHostAddress("1.2.3.4"), 0)); QCOMPARE(server.serverError(), QAbstractSocket::SocketAddressNotAvailableError); QCOMPARE(server.errorString().toLatin1().constData(), "The address is not available"); }
//---------------------------------------------------------------------------------- void tst_QTcpServer::ipv6LoopbackPerformanceTest() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 0)) { QVERIFY(server.serverError() == QAbstractSocket::UnsupportedSocketOperationError); } else { 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) { clientA.write(buffer.data(), buffer.size()); 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::constructing() { QTcpServer socket; // Check the initial state of the QTcpSocket. QCOMPARE(socket.isListening(), false); QCOMPARE((int)socket.serverPort(), 0); QCOMPARE(socket.serverAddress(), QHostAddress()); QCOMPARE(socket.maxPendingConnections(), 30); QCOMPARE(socket.hasPendingConnections(), false); QCOMPARE(socket.socketDescriptor(), -1); QCOMPARE(socket.serverError(), QAbstractSocket::UnknownSocketError); // Check the state of the socket layer? }
void tst_QTcpServer::invalidProxy() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; QFETCH(int, type); QFETCH(QString, host); QFETCH(int, port); QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(type); QNetworkProxy proxy(proxyType, host, port); QTcpServer server; server.setProxy(proxy); bool listenResult = server.listen(); QVERIFY(!listenResult); QVERIFY(!server.errorString().isEmpty()); // note: the following test is not a hard failure. // Sometimes, error codes change for the better QTEST(int(server.serverError()), "expectedError"); }
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; } } }