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 21:11 | Komunita

    Ubuntu 27.04 bude Tenacious T-Rex.

    Ladislav Hagara | Komentářů: 0
    dnes 20:44 | Nová verze

    Byla vydána nová verze 2026.4.0 "Never-slop" svobodného softwaru ScummVM (Wikipedie) umožňujícího bezproblémový běh mnoha klasických adventur na zařízeních, pro které nebyly nikdy určeny. Přehled novinek v poznámkách k vydání a na GitHubu. ScummVM oslavil 25 let. Verze 0.0.1 vyšla 8. října 2001.

    Ladislav Hagara | Komentářů: 0
    dnes 17:22 | Humor

    Kanadský vývojář Anthony Sistilli vytvořil ironický DIY projekt parodující kamerové systémy Flock, s cílem názorně demonstrovat rizika masového sledování jaké provozují tyto komerční ALPR systémy. Z levné IP kamery a vlastního ML softwaru (napsaného s pomocí SI circa za 20 minut, kód se mi bohužel nepodařilo dohledat) běžícího v laptopu sestavil jednoduchý systém, který detekuje výhradně policejní vozidla, zaznamenává jejich SPZ a

    … více »
    ❗Červivý Hřib krade❗ | Komentářů: 6
    dnes 12:44 | Upozornění

    Část údajů uživatelů internetového supermarketu Rohlík byla odcizena. Kyberútočníci napadli nástroj zákaznické podpory Rohlíku, odcizili tak jména, e-mailové adresy, v některých případech také telefonní čísla nebo přepisy komunikace mezi klienty a zákaznickou podporou. Rohlík incident nahlásil příslušným orgánům a přijal příslušné opatření, aby zamezil podobným případům v budoucnosti, uvedla firma.

    Ladislav Hagara | Komentářů: 10
    dnes 11:11 | IT novinky

    Aplikace eDoklady fungovala v obou volebních dnech stabilně a prakticky bez front. Digitální a informační agentura (DIA) odhaduje, že se digitálním dokladem prokázalo více než 100.000 voličů. Aplikaci si před volbami či během nich aktualizovalo 247.517 uživatelů. Nových registrací bylo 19.431 a do aplikace se přihlásilo 357.879 lidí. Největší nápor přišel bezprostředně po otevření volebních místností mezi 14. a 16. hodinou, kdy si

    … více »
    Ladislav Hagara | Komentářů: 7
    dnes 00:55 | Pozvánky

    Začal semestr, začal i podzim a kromě hub rostou jako po dešti i veřejné dílny v Praze. Nedávno strahováci referovali o hackerspacu Bordel, nyní se otevřela dílna Dejvice Lab jen kousek od ČVUT. Na blížící Virtuální Bastlírně tak uslyšíte nejen report z návštěvy dílny HWLab, ale i řadu novinek, událostí a úsměvných momentů, které se za poslední měsíc ve světě techniky, ale i vědy udály. Připojte se tedy již v úterý 13.10. od 20:00 a zapojte se do

    … více »
    bkralik | Komentářů: 0
    včera 11:33 | Nová verze

    Byl vydán LineageOS 24 (Mastodon). LineageOS (Wikipedie) je svobodný operační systém pro chytré telefony, tablety a set-top boxy založený na Androidu. Jedná se o nástupce CyanogenModu. LineageOS 24 je založený na Androidu 17.

    Ladislav Hagara | Komentářů: 0
    včera 03:55 | IT novinky

    Společnost Valve publikovala na svém GitLabu nákresy a schémata zapojení headsetu Steam Frame. Pro nekomerční účely.

    Ladislav Hagara | Komentářů: 1
    10.10. 23:11 | Bezpečnostní upozornění

    Soutěž Pwn2Own Ireland 2026 skončila 9. října. Bezpečnostní výzkumníci získali celkem 1 262 000 dolarů na odměnách. Během soutěže bylo předvedeno zneužití 98 zero-day zranitelností. Testování zahrnovalo různé kategorie zařízení a software. Výzkumníci předváděli prakticky fungující útoky podle pravidel soutěže. Výsledky následně slouží výrobcům při přípravě oprav. Mezi pokořenými jsou: Samsung Galaxy S26, OpenAI Codex, Oracle Autonomous AI Database, Google Pixel 10, u iPhone 17 neuspěli.

    vencour | Komentářů: 1
    9.10. 22:44 | Nová verze

    Programovací jazyk Python byl vydán v nové verzi 3.15.0. Podrobný přehled novinek v aktualizované dokumentaci.

    Ladislav Hagara | Komentářů: 20
    Které desktopové prostředí na Linuxu používáte?
     (9%)
     (7%)
     (4%)
     (21%)
     (29%)
     (8%)
     (5%)
     (2%)
     (14%)
     (20%)
    Celkem 2838 hlasů
     Komentářů: 32, poslední včera 17:02
    Rozcestník

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

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

    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ákno • Nahoru

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