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ářů: 1
    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ářů: 26
    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 512 hlasů
     Komentářů: 14, poslední včera 10:22
    Rozcestník

    Konzolové programy v Qt 4 – 4 (UDP server a klient)

    10. 11. 2009 | David Watzke | Programování | 5320×

    V tomto díle si ukážeme, jak napsat jednoduchý UDP server a klient. UDP je zkratka angl. User Datagram Protocol a je to základní internetový protokol. Hodí se spíš tam, kde se počítá se ztrátami paketů, přičemž není žádoucí odesílat je znova (hry, VoIP, internetová rádia).

    Obsah

    Co je to UDP?

    link

    UDP je zkratka angl. User Datagram Protocol a je to základní internetový protokol. Na rozdíl od minule popisovaného TCP se hodí spíš tam, kde se počítá se ztrátami paketů, přičemž není žádoucí odesílat je znova (hry, VoIP, internetová rádia). UDP totiž nezaručuje, že se odeslaná data dostanou ke svému cíli – když to nevyjde napoprvé, tak se to znova nezkouší. Nezaručuje ani pořadí, ve kterém data přijdou. Někdy se používá pro jednoduchost (DNS). Výhodou oproti TCP je nižší režie. Někdo volí UDP také kvůli vyšší flexibilitě, například když si chce kontrolu doručení naprogramovat sám nějakým velmi specifickým způsobem.

    UDP sockety v Qt

    link

    S UDP sockety se v Qt pracuje přes objekt QUdpSocket. Přes tento objekt posíláme datagramy metodou writeDatagram(), které zadáme data a adresu+port, kam je chceme poslat. Zrovna tak můžeme datagramy číst, tzn. použít socket jako server. Nejdřív je nutné socket spojit s nějakou adresou a portem pomocí metody bind() a potom lze přečíst datagram z fronty metodou readDatagram().

    Jelikož je práce se sockety v Qt docela jednoduchá a navíc práce s UDP se (až na specifické věci) podobá práci s TCP (viz díl o TCP), rozhodl jsem se udělat příklad velice prostý. Klient posílá datagramy a server je přijímá a vypisuje na standardní výstup. Oba programy jsou jako obvykle v angličtině, protože nesnesu češtinu v kódu, ale dodávám k nim českou lokalizaci.

    UDP server

    link

    Server poslouchá (napevno) na localhostu na portu 2266, tzn. 127.0.0.1:2266. Pouze čeká na příchozí datagramy a jakmile mu nějaký přijde, vypíše jeho adresáta a příchozí data. Když někdo na server pošle datagram, řekněme text „Hello World!“, tak se vypíše něco jako:

    91.121.174.105:2266 říká: Hello World!
    

    udpserver.h: API.

    #ifndef UDPSERVER_H
    #define UDPSERVER_H
    
    #include <QObject>
    #include <QAbstractSocket>
    #include <QTextStream>
    
    class QUdpSocket;
    
    class UdpServer : public QObject
    {
    	Q_OBJECT
    public:
    	UdpServer();
    
    private:
    	QUdpSocket* socket;
    	QTextStream out;
    
    private slots:
    	void readDatagrams();
    	void handleError();
    };
    
    #endif // UDPSERVER_H
    

    udpserver.cpp: Spolehlivé čtení datagramů se řeší zajímavým způsobem. Prohlédněte si slot readDatagrams(). Pro čekající datagram vytvoří proměnnou typu QByteArray na data (str), nastaví velikost tohoto pole bajtů (lze zjistit metodou socketu pendingDatagramSize()) a poté předá pomocí str.data() ukazatel char* metodě socketu readDiagram(). Přes tento ukazatel se data z datagramu přímo zapíšou do instance QByteArray, pod kterou ukazatel patří (tzn. do str).

    #include "udpserver.h"
    
    #include <QtNetwork>
    
    UdpServer::UdpServer() : out(stdout, QIODevice::WriteOnly)
    {
    	// vytvoříme UDP socket
    	socket = new QUdpSocket(this);
    	// připojíme slot pro zpracování datagramu
    	connect(socket, SIGNAL(readyRead()), SLOT(readDatagrams()));
    	// a slot pro zpracování chyb
    	connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleError()));
    
    	// pokusíme se spustit UDP server
    	if(socket->bind(QHostAddress::Any, 2266))
    	{ // spuštěno
    		out << tr("socket bound to port 2266 on all available interfaces") << endl;
    	} else
    	{ // nelze spustit
    		// touto oblezličkou zajistíme ukončení programu (po vykonání konstruktoru)
    		QTimer::singleShot(0, qApp, SLOT(quit()));
    		out << tr("couldn't bind socket to port 2266") << endl;
    	}
    }
    
    // zpracovává chybu
    void UdpServer::handleError()
    {
    	// vypíše chybovou hlášku
    	out << "error: " << socket->errorString() << endl;
    }
    
    // přečte čekající UDP datagram(y)
    void UdpServer::readDatagrams()
    {
    	// dokud jsou ve frontě nepřečtené datagramy
    	while(socket->hasPendingDatagrams())
    	{
    		// vytvoříme si pro datagram:
    		// pole bajtů (řetězec)
    		QByteArray str;
    		// adresu
    		QHostAddress addr;
    		// a port (unsigned short)
    		quint16 port;
    
    		// nastavíme poli správnou velikost
    		str.resize(socket->pendingDatagramSize());
    
    		// načteme data z datagramu
    		socket->readDatagram(str.data(), str.size(), &addr, &port);
    
    		out << addr.toString() << ":" << port << " " << tr("says") << ": "
    		    << str << endl;
    	}
    }
    

    main.cpp: Nastavíme UTF-8 pro C řetězce a lokalizaci. Načteme soubor s překladem.

    #include <QCoreApplication>
    #include <QLocale>
    #include <QTextCodec>
    #include <QTranslator>
    
    #include "udpserver.h"
    
    int main(int argc, char *argv[])
    {
    	QCoreApplication a(argc, argv);
    
    	{
    	QTextCodec* unicode = QTextCodec::codecForName("UTF-8");
    	QTextCodec::setCodecForCStrings(unicode);
    	QTextCodec::setCodecForTr(unicode);
    	}
    
    	QTranslator t;
    	t.load("udpserver_" + QLocale::system().name());
    	a.installTranslator(&t);
    
    	UdpServer s;
    
    	return a.exec();
    }
    

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

    UDP klient

    link

    Klient má jednoduchou příkazovou řádku umožňující čtyři operace: vypsat nápovědu, nastavit (či vypsat nastavenou) adresu, nastavit (či vypsat nastavený) port a odeslat UTF-8 řetězec na nastavenou adresu a port (výchozí je 127.0.0.1:2266). Pokud chcete UDP server vyzkoušet ze vzdáleného serveru, na kterém není nainstalované Qt, můžete jako klienta použít netcat v UDP režimu (-u).

    Práce s programem vypadá takto:

    $ ./udpclient
    potřebujete-li pomoc, napište "help" a zmáčkněte enter
    > help
    help		Vypíše tuto nápovědu
    host [IP]	Nastaví adresu na danou hodnotu
    port [port]	Nastaví port na danou hodnotu
    send [text]	Pošle datagram
    > host
    hostitel je nastaven na 127.0.0.1
    > host 255.255.255.255
    adresa hostitele byla nastavena na 255.255.255.255
    > host
    hostitel je nastaven na 255.255.255.255
    > port
    port je nastaven na 2266
    > send Hello World!
    odesílám diagram s textem "Hello World!" na 255.255.255.255:2266
    > ^C
    

    udpclient.h: API.

    #ifndef UDPCLIENT_H
    #define UDPCLIENT_H
    
    #include <QObject>
    #include <QHostAddress>
    #include <QTextStream>
    
    class QUdpSocket;
    
    class UdpClient : public QObject
    {
    	Q_OBJECT
    public:
    	UdpClient();
    
    private:
    	QUdpSocket* socket;
    	QTextStream out;
    
    	QHostAddress addr;
    	quint16 port;
    
    	void commandLine();
    	void processCommand(const QString& command);
    	void sendDatagram();
    
    private slots:
    	void handleError();
    };
    
    #endif // UDPCLIENT_H
    

    udpclient.cpp

    #include "udpclient.h"
    
    #include <QTextStream>
    #include <QtNetwork>  
    
    #include <cstdio>
    
    UdpClient::UdpClient() :
    	// nastavíme pro výpis na std. výstup
    	out(stdout, QIODevice::WriteOnly),   
    	// výchozí adresa je 127.0.0.1:2266  
    	addr(QHostAddress::LocalHost), port(2266)
    {						
    	// vytvoříme UDP socket		  
    	socket = new QUdpSocket(this);	   
    	// připojíme k němu slot pro zpracování chyb
    	connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(handleError()));
    
    	this->commandLine();
    }			      
    
    // vypíše chybu
    void UdpClient::handleError()
    {			    
    	out << tr("socket error:") << " " << socket->errorString() << endl;
    }
    
    // zpracuje příkaz
    void UdpClient::processCommand(const QString& command)
    {
    	// příkaz
    	QString cmd = command.section(' ', 0, 0);
    	// a jeho argumenty
    	QString str = "";
    
    	//qDebug() << "command:" << command << "cmd:" << cmd;
    
    	// pokud je příkaz prázdný, nastavíme výchozí (help)
    	if(cmd.isEmpty())				   
    		cmd = "help";			       
    	else // jinak si uložíme argumenty příkazu	  
    		str = command.mid(cmd.size()+1);	    
    
    	if(cmd == "host")
    	{		
    		if(str.isEmpty())
    		{ // pokud nemá argumenty, vypíšeme aktuální adresu
    			out << tr("host is set to %1").arg(addr.toString()) << endl;
    			return;	
    		}
    
    		// uložíme aktuální adresu
    		QHostAddress prevAddr(addr);
    
    		// nastavíme novou adresu
    		if(addr.setAddress(str)) 
    		{			
    			out << tr("host address has been set to %1")
    				    .arg(addr.toString()) << endl;  
    		} else	
    		{ // a když to selže (nesprávný formát adresy), nastavíme zpátky tu předchozí
    			out << tr("couldn't set the given host address: %1"
    				    .arg(str) << endl; 
    			addr = prevAddr;
    		}
    	} else	
    	if(cmd == "port")
    	{
    		if(str.isEmpty())
    		{ // pokud nemá argumenty, vypíšeme aktuální port
    			out << tr("port is set to %1").arg(port) << endl;	
    			return;
    		}
    
    		// kontrola konverze stringu na integer
    		bool ok;			       
    		// převedeme argument na int	   
    		int p = str.toInt(&ok);	    
    
    		// pokud byla konverze úspěšná a port je v rozsahu, nastavíme jej
    		// jako aktuální
    		if(ok && p >= 0 && p < 65536)	      
    		{
    			port = (quint16) p;
    			out << tr("port has been set to %1").arg(port) << endl;
    		} else
    		{
    			out << tr("couldn't set port to %1").arg(str) << endl;
    		}
    	} else
    	if(cmd == "send")
    	{
    		// pokud byl zadán argument, odešleme datagram
    		if(str.isEmpty())
    		{
    			out << tr("nothing to send, aborting") << endl;
    		} else
    		{
    			out << tr("sending datagram with text \"%1\" to %2:%3")
    				    .arg(str).arg(addr.toString()).arg(port) << endl;
    
    			socket->writeDatagram(str.toUtf8(), addr, port);
    		}
    	} else
    	{
    		// pokud byl zadán neplatný příkaz, informujeme o tom
    		if(cmd != "help")
    			out << tr("error: unknown command: %1").arg(cmd) << endl;
    		// vypíšeme nápovědu
    		out << "help\t\t\t" << tr("Prints this help")
    		    << "\nhost [IP]\t\t" << tr("Sets the address to a given value")
    		    << "\nport [port]\t\t" << tr("Sets the port to a given value")
    		    << "\nsend [text]\t\t" << tr("Sends a datagram") << endl;
    	}
    }
    
    void UdpClient::commandLine()
    {
    	out << tr("if you need help, type `help' and hit return") << endl;
    
    	// objekt pro čtení ze std. vstupu
    	QTextStream in(stdin, QIODevice::ReadOnly);
    	// řetězec, do kterého budeme ukládat std. vstup
    	QString input;
    
    	// hlavní smyčka
    	forever // klíčové slovo Qt, totéž jako for(;;)
    	{
    		// vypíšeme prompt
    		out << "> "; out.flush();
    		// načteme řádek ze std. vstupu
    		input = in.readLine(512+5);
    		// zpracujeme načtený řádek (příkaz)
    		this->processCommand(input);
    	}
    }
    

    main.cpp

    #include <QCoreApplication>
    #include <QLocale>
    #include <QTextCodec>
    #include <QTranslator>
    
    #include "udpclient.h"
    
    int main(int argc, char *argv[])
    {
    	QCoreApplication a(argc, argv);
    
    	{
    	QTextCodec* unicode = QTextCodec::codecForName("UTF-8");
    	QTextCodec::setCodecForCStrings(unicode);
    	QTextCodec::setCodecForTr(unicode);
    	}
    
    	QTranslator t;
    	t.load("udpclient_" + QLocale::system().name());
    	a.installTranslator(&t);
    
    	UdpClient main;
    
    	return a.exec();
    }
    

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

           

    Hodnocení: 80 %

            š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ář

    10.11.2009 08:24 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    Pouze čeká na příchozí datagramy a jakmile mu nějaký přijde, vypíše jeho adresáta a příchozí data.
    ...vypíše jeho odesílatele...
    Quando omni flunkus moritati
    David Watzke avatar 10.11.2009 11:39 David Watzke | skóre: 74 | blog: Blog... | Praha
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    Přesně tak. Jen jsem vás zkoušel.
    “Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
    10.11.2009 08:51 T.O.M. | skóre: 22 | blog: T.O.M.'s blog | Ostrava
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    Příloha:

    Mám dotaz trochu off topic: Je to nějaká nová fíčura Abíčka, že se mi rozbalovací boxy se zdrojáky nahrazují plně rozbaleným textem? Prý nejaký JavaScript code syntax highlighter Alexe Gorbatcheva, viz. přiložený obrázek...

    Předchozí díly tohoto seriálu to nedělají a v mém profilu jsem vypinač nenašel.

    David Watzke avatar 10.11.2009 11:41 David Watzke | skóre: 74 | blog: Blog... | Praha
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    To je bug v kombinaci toho editoru s ábíčkem. Místo toho tlačítka Rozbalit se nahoře ukáže kód toho tlačítka :-D Už jsem to nahlásil.
    “Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
    13.11.2009 00:26 guest
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    zdravim, dekuji pekne... jinak nevim proc toho clienta obalujete, myslim ze pro nazornost a prehlednost by to stacilo bez te omacky.
    2.7.2015 17:48 vladinux
    Rozbalit Rozbalit vše Re: Konzolové programy v Qt 4 – 4 (UDP server a klient)
    Zdravím, ide o framework alebo kód je natívny?

    Založit nové vláknoNahoru

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