abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 01:33 | Zajímavý projekt

    Singularity je rootkit ve formě jaderného modulu (Linux Kernel Module), s otevřeným zdrojovým kódem dostupným pod licencí MIT. Tento rootkit je určený pro moderní linuxová jádra 6.x a poskytuje své 'komplexní skryté funkce' prostřednictvím hookingu systémových volání pomocí ftrace. Pro nadšence je k dispozici podrobnější popis rootkitu na blogu autora, případně v článku na LWN.net. Projekt je zamýšlen jako pomůcka pro bezpečnostní experty a výzkumníky, takže instalujte pouze na vlastní nebezpečí a raději pouze do vlastních strojů 😉.

    NUKE GAZA! 🎆 | Komentářů: 0
    včera 21:22 | Zajímavý projekt

    Iconify je seznam a galerie kolekcí vektorových open-source ikon, ke stažení je přes 275000 ikon z více jak dvou set sad. Tento rovněž open-source projekt dává vývojářům k dispozici i API pro snadnou integraci svobodných ikon do jejich projektů.

    NUKE GAZA! 🎆 | Komentářů: 0
    včera 03:33 | IT novinky

    Dle plánu certifikační autorita Let's Encrypt nově vydává také certifikáty s šestidenní platností (160 hodin) s možností vystavit je na IP adresu.

    Ladislav Hagara | Komentářů: 8
    17.1. 14:44 | Nová verze

    V programovacím jazyce Go naprogramovaná webová aplikace pro spolupráci na zdrojových kódech pomocí gitu Forgejo byla vydána ve verzi 14.0 (Mastodon). Forgejo je fork Gitei.

    Ladislav Hagara | Komentářů: 3
    17.1. 13:11 | Zajímavý projekt

    Just the Browser je projekt, 'který vám pomůže v internetovém prohlížeči deaktivovat funkce umělé inteligence, telemetrii, sponzorovaný obsah, integraci produktů a další nepříjemnosti' (repozitář na GitHubu). Využívá k tomu skrytá nastavení ve webových prohlížečích, určená původně pro firmy a organizace ('enterprise policies'). Pod linuxem je skriptem pro automatickou úpravu nastavení prozatím podporován pouze prohlížeč Firefox.

    NUKE GAZA! 🎆 | Komentářů: 3
    16.1. 16:44 | Nová verze

    Svobodný multiplatformní herní engine Bevy napsaný v Rustu byl vydán ve verzi 0.18. Díky 174 přispěvatelům.

    Ladislav Hagara | Komentářů: 2
    16.1. 15:11 | IT novinky

    Miliardy korun na digitalizaci služeb státu nestačily. Stát do ní v letech 2020 až 2024 vložil víc než 50 miliard korun, ale původní cíl se nepodařilo splnit. Od loňského února měly být služby státu plně digitalizované a občané měli mít právo komunikovat se státem digitálně. Do tohoto data se povedlo plně digitalizovat 18 procent agendových služeb státu. Dnes to uvedl Nejvyšší kontrolní úřad (NKÚ) v souhrnné zprávě o stavu digitalizace v Česku. Zpráva vychází z výsledků víc než 50 kontrol, které NKÚ v posledních pěti letech v tomto oboru uskutečnil.

    Ladislav Hagara | Komentářů: 25
    16.1. 13:55 | IT novinky

    Nadace Wikimedia, která je provozovatelem internetové encyklopedie Wikipedia, oznámila u příležitosti 25. výročí vzniku encyklopedie nové licenční dohody s firmami vyvíjejícími umělou inteligenci (AI). Mezi partnery encyklopedie tak nově patří Microsoft, Amazon a Meta Platforms, ale také start-up Perplexity a francouzská společnost Mistral AI. Wikimedia má podobnou dohodu od roku 2022 také se společností Google ze skupiny

    … více »
    Ladislav Hagara | Komentářů: 0
    16.1. 02:22 | Nová verze

    D7VK byl vydán ve verzi 1.2. Jedná se o fork DXVK implementující překlad volání Direct3D 5, 6 a 7 na Vulkan. DXVK zvládá Direct3D 8, 9, 10 a 11.

    Ladislav Hagara | Komentářů: 0
    16.1. 02:00 | Nová verze

    Byla vydána verze 12.0.0 knihovny libvirt (Wikipedie) zastřešující různé virtualizační technologie a vytvářející jednotné rozhraní pro správu virtuálních strojů. Současně byl ve verzi 12.0.0 vydán související modul pro Python libvirt-python. Přehled novinek v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    Které desktopové prostředí na Linuxu používáte?
     (18%)
     (5%)
     (0%)
     (9%)
     (19%)
     (3%)
     (5%)
     (2%)
     (11%)
     (39%)
    Celkem 510 hlasů
     Komentářů: 14, poslední včera 10:22
    Rozcestník

    Konzolové programy v Qt 4 – 3 (TCP server)

    16. 9. 2009 | David Watzke | Programování | 6776×

    V tomto díle si ukážeme, jak za použití modulu QtNetwork naprogramovat jednoduchý TCP server.

    Tento díl seriálu úzce souvisí s článkem Grafické programy v Qt 4 – 8 (TCP klient), jelikož je o server, jehož klienta jsem napsal s grafickým rozhraním. Základní informace o TCP síťování, socketech v Qt a ukázkovém programu se dočtete tam, zatímco tento článek popisuje čistě serverovou část, takže doporučuji začít čtení odkazovaným článkem.

    TCP server

    Teď, když chápeme komunikaci přes QTcpSocket, můžeme se vrhnout na serverovou část. Základem je třída QTcpServer. Hned po vytvoření instance je vhodné nastavit nějaké základní parametry serveru, například takto:

    QTcpServer* server = new QTcpServer(this);
    // explicitně zakážeme použití proxy
    server->setProxy(QNetworkProxy::NoProxy);
    // nastavíme max. počet spojení
    server->setMaxPendingConnections(50);
    

    Ve většině případů je dobré zpracovat signál newConnection(), kterým nás server informuje o novém příchozím spojení. Slot, který na tento signál napojíme, bude chtít nejspíš získat socket tohoto nového spojení. K tomu využijeme metodu nextPendingConnection(), a to následovně:

    // získáme socket
    QTcpSocket* socket = server->nextPendingConnection();
    // dobré je hned ověřit, zda ještě existuje (tj. zda metoda nevrátila 0)
    if(!socket)
    	return;
    

    Existují dvě alternativy k tomuto přístupu zpracování nových příchozích spojení a jejich použití záleží na tom, čeho přesně chcete dosáhnout. Pokud potřebujete provádět něco velmi specifického a vyžadujete vysokou flexibilitu, potom si celou událost můžete zpracovat sami, a to tak, že si vytvoříte vlastní třídu založenou na QTcpServer a reimplementujete její chráněnou virtuální metodu incomingConnection(int socketDescriptor). Integer, který dostanete jako argument, je popisovač (descriptor) socketu a pokud nepoužíváte QNetworkProxy, lze s ním pracovat pomocí nativních socketových funkcí.

    Druhý alternativní způsob je podstatně jednodušší. Nejdřív je třeba spustit server (viz níže) a potom lze použít blokující metodu waitForNewConnection(), které lze zadat čas v milisekundách (jak dlouho má čekat na příchozí připojení) a ukazatel na bool, do kterého se uloží informace o tom, zda došlo k vypršení času (tedy false znamená, že máte nové spojení).

    Když máme připravené zpracování nových připojení, můžeme spustit server, tedy naslouchání na určité adrese (nebo více adresách) a portu. Třeba takto:

    QString ip("127.0.0.1");
    
    QHostAddress addr;
    if(!addr.setAddress(ip))
    { // zadaná IP adresa není ve správném formátu
    	return 1;
    }
    
    // port=0 zajistí automatický výběr portu
    server->listen(addr, 0);
    

    TODO server

    Ještě než server spustíte, je třeba vytvořit mu konfigurační soubor, kam zapíšete platná uživatelská jména (bez mezer) a přiřadíte jim hesla (resp. jejich SHA1 hash). Chcete-li vytvořit uživatele user s heslem pass, tak si nejdřív zjistěte SHA1 hash řetězce „pass“:

    $ echo -n "pass" | sha1sum
    9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684
    

    Když máte hash, vytvořte si konfigurační soubor v textovém editoru (na UNIXech ~/.config/watzke.cz/todoserver.conf) a přidejte do něj sekci [logins] a vaším uživatelem.

    [logins]
    user=9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684
    

    Server komunikuje jednoduchým protokolem, který je zdokumentovaný ve výše odkazovaném článku. Obsahuje jednoduchou obranu před bruteforce přihlašováním – povolí maximálně 10 chybných přihlášení za minutu. Jde spíše jen o ukázku implementace takové věci, spíš než cokoliv jiného, nicméně crackera by to mělo zpomalit :-)

    Samozřejmě teď lze namítnout, že zmiňovat crackery je výsměch, když nepoužívám SSL sockety (nebo jiný způsob šifrování), ale o to mi v této ukázce nejde. Nicméně, když najdete bezpečnostní chybu, která s tímto nesouvisí, určitě se ozvěte v diskusi. Ještě dodám, že o chybějícím limitu délky jednotlivých záznamů vím, může tam být (teoreticky) libovolně dlouhý řetězec, i když můj klient umožní max. 32767 (2^15-1) znaků. Sám jsem několik bezpečnostních chyb odhalil a opravil při testování. Zvlášť při psaní síťového serveru, kde se řeší přihlašování, je třeba korektně ošetřovat nejrůznější výjimky. Nikdy nespoléhejte pouze na kontroly ve vašem klientovi.

    tcpserver.h: API.

    #ifndef TCPSERVER_H
    #define TCPSERVER_H
    
    #include <QObject>
    #include <QTextStream>
    #include <QList>
    #include <QPair>
    #include <QHostAddress>
    #include <QHash>
    #include <QSettings>
    
    class QTcpServer;
    class QTcpSocket;
    
    class TcpServer : public QObject
    {
    	Q_OBJECT
    public:
    	TcpServer(QHostAddress addr = QHostAddress(QHostAddress::Any),
    		  int port = 2266);
    
    private:
    	QTcpServer* server;
    	QTextStream cerr;
    	QHash<QTcpSocket*, QString> logins;
    	QHash<QString, int> log;
    
    	QSettings settings;
    
    	void login(QTcpSocket* socket, const QString& user, const QString& pass,
    		   bool force = false);
    	QString getKey(QString user, int index);
    	void sortKeys(QString user);
    
    	void listItems(QTcpSocket* socket);
    	void addItem(QTcpSocket* socket, QString item);
    	void removeItems(QTcpSocket* socket, QList<QByteArray> keys);
    
    	void socketWrite(QTcpSocket* socket, QByteArray data);
    
    private slots:
    	void purgeLog();
    	void handleNewConnection();
    	void reply();
    	void gotDisconnected();
    };
    
    #endif // TCPSERVER_H
    

    tcpserver.cpp:

    #include "tcpserver.h"
    
    #include <QtNetwork>
    #include <cstdio>
    
    TcpServer::TcpServer(QHostAddress addr, int port)
    	: cerr(stderr, QIODevice::WriteOnly) // poslouží pro výpis na std. chybový výstup,
    					     // podobně jako std::cerr v C++
    {
    	// vytvoříme TCP server
    	server = new QTcpServer(this);
    
    	// zajistíme zpracování požadavků vlastním slotem
    	connect(server, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));
    
    	// každou minutu pročistíme záznam přihlašování
    	QTimer::singleShot(60*1000, this, SLOT(purgeLog()));
    
    	// explicitně zakážeme použití proxy
    	server->setProxy(QNetworkProxy::NoProxy);
    	// nastavíme max. počet spojení
    	server->setMaxPendingConnections(50);
    
    	// nastavíme IP a port pro naslouchání
    	bool listening = server->listen(addr, port);
    
    	// uložíme si IP adresu s portem do řetězce ve tvaru IP:port (jen pro výpis)
    	QString ipport = addr.toString() + ":" + QString::number(port);
    
    	// pokud se TCP server nepodařilo spustit na dané IP a portu
    	if(not listening)
    	{
    		// vypíšeme chybovou hlášku
    		cerr << tr("couldn't bind to %1, quitting…").arg(ipport) + "\n";
    		// zajistíme okamžitý zápis na stderr
    		cerr.flush();
    		// tímto zajistíme ukončení programu po provedení konstruktoru
    		QTimer::singleShot(0, qApp, SLOT(quit()));
    	} else
    	{
    		cerr << tr("listening on %1").arg(ipport) + "\n";
    		cerr.flush();
    	}
    }
    
    // (ihned) zapíše data do socketu
    void TcpServer::socketWrite(QTcpSocket* socket, QByteArray data)
    {
    	// zapíše data
    	socket->write(data);
    	// vynutí okamžitý zápis čekajících dat
    	socket->flush();
    }
    
    // vyprázdní záznam o přihlašování
    void TcpServer::purgeLog()
    {
    	log.clear();
    }
    
    // zpracuje nové příchozí spojení
    void TcpServer::handleNewConnection()
    {
    	// získáme socket
    	QTcpSocket* socket = server->nextPendingConnection();
    	if(!socket)
    		return;
    
    	cerr << tr("incoming connection from ") << socket->peerAddress().toString() << "\n";
    	cerr.flush();
    
    	// komunikace s klientem
    	connect(socket, SIGNAL(readyRead()), SLOT(reply()));
    	// šetříme paměť a zajistíme smazání socketu po jeho odpojení
    	connect(socket, SIGNAL(disconnected()), SLOT(gotDisconnected()));
    
    	// požádáme klienta, aby se přihlásil
    	this->socketWrite(socket, "LOGIN");
    }
    
    // vyřizuje odpověď na příchozí požadavky
    void TcpServer::reply()
    {
    	// získáme socket (skrz objekt, který vyslal signál)
    	QTcpSocket* socket = qobject_cast<QTcpSocket*>(this->sender());
    
    	if(log.value(socket->peerAddress().toString(), 0) >= 10)
    		this->socketWrite(socket, "TOOMANYWRONGLOGINS");
    
    	// požadavek
    	QByteArray rawdata = socket->readAll();
    	// argumenty požadavku
    	QList<QByteArray> args = rawdata.split(' ');
    	// samotný příkaz
    	QString command = args.takeFirst();
    	// přihlašovací/uživatelské jméno
    	QString user = logins.value(socket);
    
    	qDebug() << rawdata;
    
    	if(command == "LOGIN" || command == "FORCELOGIN")
    	{ // klient se chce přihlásit
    		// klient je již přihlášen (na tomto socketu)
    		if(!user.isEmpty())
    		{
    			this->socketWrite(socket, "ALREADYLOGGED");
    			return;
    		}
    
    		// vynucené přihlášení?
    		bool force = (command == "FORCELOGIN");
    		// heslo
    		QString pass;
    
    		// špatný počet argumentů nebudeme tolerovat
    		if(args.size() == 2)
    		{
    			user = args.at(0);
    			pass = args.at(1);
    		}
    
    		// zahájíme přihlašování
    		this->login(socket, user, pass, force);
    		return;
    	}
    
    	if(user.isEmpty())
    	{
    		socket->disconnectFromHost();
    
    		QString ip(socket->peerAddress().toString());
    		cerr << tr("a client (IP=%1) has requested something without being logged in,").arg(ip)
    		     << "\n" << tr("which is suspicious – closing the connection.") << "\n";
    		cerr.flush();
    	}
    
    	if(command == "LIST")
    	{ // klient žádá o seznam svých TODO položek
    		this->listItems(socket);
    	} else
    	if(command == "ADD")
    	{ // klient si přeje přidat novou TODO položku
    		this->addItem(socket, rawdata.right( rawdata.size()-command.size()-1 ));
    	} else
    	if(command == "REMOVE")
    	{ // klient si přeje odstranit položky
    		this->removeItems(socket, rawdata.right( rawdata.size()-command.size()-1 )
    						 .split(' '));
    	} else
    	{ // klient poslal neplatný příkaz
    		this->socketWrite(socket, "INVALIDCMD");
    
    		cerr << "invalid command: " << command << "\n";
    		cerr.flush();
    
    		return;
    	}
    }
    
    // přihlásí uživatele
    void TcpServer::login(QTcpSocket* socket, const QString& user,
    		      const QString& pass, bool force)
    {
    	//qDebug() << "user" << user << "is trying to log in with pass" << pass;
    
    	// načteme správné heslo
    	QString realpass = settings.value(QString("logins/%1").arg(user)).toString();
    
    	// a porovnáme jej se zadaným (navíc se ujistíme, zda uživatel vůbec existuje,
    	// abychom ošetřili přihlášení bez hesla)
    	if(!user.isEmpty() && !realpass.isEmpty() && pass == realpass)
    	{ // ok
    		// zjistíme, zda je uživatel již přihlášen odjinud
    		bool alreadyLogged = logins.values().contains(user);
    
    		// pokud ano a nejde o vynucený login…
    		if(alreadyLogged and not force)
    		{
    			// informujeme o tom klienta
    			this->socketWrite(socket, "ALREADYLOGGED");
    			return;
    		}
    
    		// pokud ano a jde o vynucený login…
    		if(alreadyLogged)
    		{
    			// získáme seznam všech socketů
    			QList<QTcpSocket*> keys = logins.keys();
    
    			// a odpojíme ten, který je přihlášený pod daným jménem
    			for(int i=0; i<keys.size(); i++)
    				if(logins.value(keys.at(i)) == user)
    				{
    					QTcpSocket* oldSocket = keys.at(i);
    					oldSocket->disconnectFromHost();
    
    					logins.remove(oldSocket);
    					break;
    				}
    		}
    
    		// pošleme odpověď
    		this->socketWrite(socket, "LOGGED");
    
    		// přiřadíme si socket k uživatelskému jménu do seznamu přihlášení
    		logins.insert(socket, user);
    
    		cerr << tr("user %1 successfully logged in").arg(user) << "\n";
    		cerr.flush();
    
    	} else
    	{ // špatný login
    		this->socketWrite(socket, "WRONGLOGIN");
    
    		// odpojíme klienta
    		socket->disconnectFromHost();
    
    		// zaznamenáme chybný login
    		QString ip(socket->peerAddress().toString());
    		log.insert(ip, log.value(ip, 0)+1);
    
    		cerr << tr("user %1 tried to log in with a wrong password, "
    				   "closing the connection").arg(user) << "\n";
    		cerr.flush();
    	}
    }
    
    // opraví klíče (indexy) položek v nastavení tak, aby šly po sobě (000 až 999)
    void TcpServer::sortKeys(QString user)
    {
    	// získáme seznam klíčů
    	QStringList keys = settings.allKeys();
    
    	// seznam je skutečně plný, nedá se nic dělat
    	if(keys.size() > 999)
    		return;
    
    	cerr << tr("re-sorting %1's todo list").arg(user) + "\n";
    	cerr.flush();
    
    	// získáme seznam položek
    	QStringList items;
    	foreach(QString key, keys)
    		items << settings.value(key).toString();
    
    	//qDebug() << "items:" << items;
    
    	// odstraníme všechny položky
    	settings.remove("");
    
    	// a přidáme je zpátky se správnými klíči
    	for(int key = 0; key < keys.size(); key++)
    		settings.setValue(this->getKey(user, key), items.at(key));
    
    	settings.sync();
    }
    
    // vrátí klíč (index), pod kterým se položka uloží
    QString TcpServer::getKey(QString user, int index)
    {
    	QString key = QString::number(index);
    
    	if(index < 10) // pokud je index menší než 10
    		key.prepend("00"); // přidáme dvě nuly (5 -> 005), atd.
    	else if(index < 100)
    		key.prepend("0");
    	else if(index < 1000)
    		Q_UNUSED(key)
    	else
    	{ // index je vyšší než 999, zkusíme to ještě zachránit
    		// zkusíme opravit indexy
    		this->sortKeys(user);
    
    		// načteme poslední index a přičteme k němu 1
    		int nIndex = settings.allKeys().last().toInt() + 1;
    
    		// pokud je menší než 1000, povedlo se…
    		if(nIndex < 1000)
    			key = this->getKey(user, nIndex);
    		else    // prázdný klíč = plný seznam
    			key.clear();
    	}
    
    	return key;
    }
    
    // odešle klientovi seznam jeho položek
    void TcpServer::listItems(QTcpSocket* socket)
    {
    	// načteme si uživatelské jméno
    	QString user = logins.value(socket);
    
    	// odpověď
    	QByteArray reply;
    
    	settings.beginGroup("todolist_" + user);
    	QStringList keys = settings.allKeys();
    
    	// přidáme do odpovědi seznam všech položek
    	foreach(QString key, keys)
    		reply += settings.value(key).toString() + '\n';
    
    	settings.endGroup();
    
    	// ořízneme poslední \n
    	reply.chop(1);
    
    	// přidáme odpovídající příkaz
    	if(reply.isEmpty())
    		reply = "LISTEMPTY";
    	else
    		reply.prepend("LISTING ");
    
    	//qDebug() << reply;
    
    	// a odpovíme
    	this->socketWrite(socket, reply);
    }
    
    // přidá položku do seznamu uživatele
    void TcpServer::addItem(QTcpSocket* socket, QString item)
    {
    	QString user = logins.value(socket);
    
    	settings.beginGroup("todolist_" + user);
    
    	// zjistíme, pod kterým klíčem/indexem položku uložit
    	int index;
    	if(settings.allKeys().size() > 0)
    		// k poslednímu uloženému indexu přičteme 1
    		index = settings.allKeys().last().toInt() + 1;
    	else    // první index bude 0
    		index = 0;
    
    	//qDebug() << "index:" << index;
    
    	// získáme klíč ve správném formátu
    	QString key = this->getKey(user, index);
    	// prázdný klíč = plný seznam
    	if(key.isEmpty())
    	{
    		// informujeme klienta, že má plný seznam TODO
    		this->socketWrite(socket, "LISTFULL");
    
    		// nezapomeneme ukončit skupinu!
    		settings.endGroup();
    
    		cerr << tr("user %1 has got a full todo list").arg(user) << "\n";
    		cerr.flush();
    		return;
    	}
    
    	// uložíme položku
    	settings.setValue(key, item);
    
    	// sestrojíme odpověď
    	QByteArray reply = "ADDED ";
    	reply += settings.value(key).toString();
    
    	settings.endGroup();
    
    	// odešleme odpověď
    	this->socketWrite(socket, reply);
    
    	// zapíšeme změny v TODO
    	settings.sync();
    }
    
    // odstraní vybrané položky ze seznamu
    void TcpServer::removeItems(QTcpSocket* socket, QList<QByteArray> keys)
    {
    	QString user = logins.value(socket);
    
    	QByteArray reply = "REMOVED";
    
    	settings.beginGroup("todolist_" + user);
    	QStringList savedKeys = settings.allKeys();
    
    	foreach(QByteArray key, keys)
    	{
    		int index = key.toInt();
    		settings.remove(savedKeys.at(index));
    		reply += " " + key;
    	}
    
    	settings.endGroup();
    	settings.sync();
    
    	this->socketWrite(socket, reply);
    }
    
    // klient se odpojil
    void TcpServer::gotDisconnected()
    {
    	// získáme ukazatel na objekt (socket), který vyslal signál
    	QTcpSocket* socket = qobject_cast<QTcpSocket*>( this->sender() );
    
    	// získáme přihlašovací jméno
    	QString user = logins.value(socket);
    
    	if(user.isEmpty())
    		user = "*not logged*";
    	else    // odstraníme ze seznamu aktivních připojení
    		logins.remove(socket);
    
    	// smažeme socket
    	socket->deleteLater();
    
    	cerr << tr("a client (%1) has disconnected").arg(user) << "\n";
    	cerr.flush();
    }
    

    main.cpp:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QHostAddress>
    #include <QStringList>
    #include <QTextCodec>
    
    #include "tcpserver.h"
    
    int main(int argc, char *argv[])
    {
    	QCoreApplication a(argc, argv);
    
    	// výchozí port
    	int port = 2266;
    	// výchozí adresa pro naslouchání
    	QHostAddress addr(QHostAddress::Any);
    	// je vše v pořádku pro spuštění programu?
    	bool ok = true;
    
    	// kontrola argumentů na příkazovém řádku
    	if(argc > 3)
    	{
    		ok = false;
    	} else
    	{
    		if(argc == 3)
    			port = a.arguments().at(2).toInt(&ok);
    
    		if(argc > 1)
    			ok = addr.setAddress(a.arguments().at(1));
    	}
    
    	if(not ok)
    	{
    		qDebug() << "usage:" << argv[0] << "[IP(0.0.0.0)] [port(2266)]";
    		return 1;
    	}
    
    	a.setApplicationName("todoserver");
    	a.setOrganizationDomain("watzke.cz");
    
    	// nastavíme kódování C řetězců
    	QTextCodec::setCodecForCStrings( QTextCodec::codecForName("UTF-8") );
    
    	TcpServer s(addr, port);
    
    	return a.exec();
    }
    

    Zdrojáky si můžete stáhnout v archívu tcpserver.tar.bz2.

           

    Hodnocení: 100 %

            špatnédobré        

    Nástroje: Tisk bez diskuse

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    progdan avatar 16.9.2009 02:39 progdan | skóre: 34 | blog: Archař | Teplice/Brno
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 3 (TCP server)
    Odkaz v uvodu clanku odkazuje asi jinam nez by mel :-) Ale jinak skvely pocteni Davide
    Collecting data is only the first step toward wisdom, but sharing data is the first step toward the community.
    David Watzke avatar 16.9.2009 06:49 David Watzke | skóre: 74 | blog: Blog... | Praha
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 3 (TCP server)
    Odkaz v uvodu clanku odkazuje asi jinam nez by mel :-)
    Jo, díky. To je tím, že ten článek měl původně č. 9, ale nakonec předběhl původní osmičku :-) To pak musí opravit někdo z vyšších adminů.
    Ale jinak skvely pocteni Davide
    To jsem rád, díky.
    “Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
    16.9.2009 09:34 Robert Krátký | skóre: 94 | blog: Robertův bloček
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 3 (TCP server)
    Sorry, opravil jsem článek a zapomněl přizpůsobit odkazy. Už by to mělo být v pořádku.
    16.9.2009 08:22 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 3 (TCP server)
    a potom lze použít blokovací metodu waitForNewConnection()
    spíš bych napsal blokující. Blokovací vyznívá tak, že účelem té metody je blokovat.
    Quando omni flunkus moritati
    25.12.2015 10:11 trickyapovery
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 3 (TCP server)
    Možná se najdou i lidi(jako jsem já), kteří článek z abclinuxu "drze" testují na windows a tak by asi neškodilo zmínit, že v takovém případě se ve výchozím nastavení nepoužije konfigurační soubor, ale registr windows. Tzn. je nutné ručně vytvořit podklíč HKCU\Software\watzke.cz\todoserver\logins\ a zde pro každého uživatele řetězcovou hodnotu, kde její název je uživatel a její hodnota je sha1 hesla. (pokud teda zůstane beze změny příkaz a.setApplicationName("todoserver"); a taky a.setOrganizationDomain("watzke.cz"); v main.cpp), jinak se podklíče musí adekvátně změnit. Jinak se mi článek líbí...

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.