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í
×
    včera 02:11 | Komunita

    Všem čtenářkám a čtenářům AbcLinuxu krásné Vánoce.

    Ladislav Hagara | Komentářů: 15
    včera 02:00 | Nová verze

    Byla vydána nová verze 7.0 linuxové distribuce Parrot OS (Wikipedie). S kódovým názvem Echo. Jedná se o linuxovou distribuci založenou na Debianu a zaměřenou na penetrační testování, digitální forenzní analýzu, reverzní inženýrství, hacking, anonymitu nebo kryptografii. Přehled novinek v příspěvku na blogu.

    Ladislav Hagara | Komentářů: 0
    23.12. 18:33 | Nová verze

    Vývojáři postmarketOS vydali verzi 25.12 tohoto před osmi lety představeného operačního systému pro chytré telefony vycházejícího z optimalizovaného a nakonfigurovaného Alpine Linuxu s vlastními balíčky. Přehled novinek v příspěvku na blogu. Na výběr jsou 4 uživatelská rozhraní: GNOME Shell on Mobile, KDE Plasma Mobile, Phosh a Sxmo.

    Ladislav Hagara | Komentářů: 0
    23.12. 13:55 | Nová verze

    Byla vydána nová verze 0.41.0 multimediálního přehrávače mpv (Wikipedie) vycházejícího z přehrávačů MPlayer a mplayer2. Přehled novinek, změn a oprav na GitHubu. Požadován je FFmpeg 6.1 nebo novější a také libplacebo 6.338.2 nebo novější.

    Ladislav Hagara | Komentářů: 0
    23.12. 12:44 | Nová verze

    Byla vydána nová verze 5.5 (novinky) skriptovacího jazyka Lua (Wikipedie). Po pěti a půl letech od vydání verze 5.4.

    Ladislav Hagara | Komentářů: 0
    22.12. 23:44 | Nová verze

    Byla vydána nová verze 5.4.0 programu na úpravu digitálních fotografií darktable (Wikipedie). Z novinek lze vypíchnout vylepšenou podporu Waylandu. Nejnovější darktable by měl na Waylandu fungovat stejně dobře jako na X11.

    Ladislav Hagara | Komentářů: 0
    21.12. 05:00 | Nová verze

    Byla vydána beta verze Linux Mintu 22.3 s kódovým jménem Zena. Podrobnosti v přehledu novinek a poznámkách k vydání. Vypíchnout lze, že nástroj Systémová hlášení (System Reports) získal mnoho nových funkcí a byl přejmenován na Informace o systému (System Information). Linux Mint 22.3 bude podporován do roku 2029.

    Ladislav Hagara | Komentářů: 2
    21.12. 01:55 | Nová verze

    GNU Project Debugger aneb GDB byl vydán ve verzi 17.1. Podrobný přehled novinek v souboru NEWS.

    Ladislav Hagara | Komentářů: 0
    19.12. 17:22 | IT novinky

    Josef Průša oznámil zveřejnění kompletních CAD souborů rámů tiskáren Prusa CORE One a CORE One L. Nejsou vydány pod obecnou veřejnou licenci GNU ani Creative Commons ale pod novou licencí OCL neboli Open Community License. Ta nepovoluje prodávat kompletní tiskárny či remixy založené na těchto zdrojích.

    Ladislav Hagara | Komentářů: 14
    19.12. 17:00 | Komunita

    Nový CEO Mozilla Corporation Anthony Enzor-DeMeo tento týden prohlásil, že by se Firefox měl vyvinout v moderní AI prohlížeč. Po bouřlivých diskusích na redditu ujistil, že v nastavení Firefoxu bude existovat volba pro zakázání všech AI funkcí.

    Ladislav Hagara | Komentářů: 1
    Kdo vám letos nadělí dárek?
     (33%)
     (2%)
     (10%)
     (2%)
     (1%)
     (2%)
     (16%)
     (19%)
     (14%)
    Celkem 83 hlasů
     Komentářů: 18, poslední včera 15:30
    Rozcestník

    Dotaz: sockety a c++

    8.11.2010 15:10 pedraz
    sockety a c++
    Přečteno: 839×
    Zdravím potřeboval bych poradit s aplikací klient-server: Klient každou minutu posílá data serveru, který je pak dál zpracovává. Jde mi o to jak udělat, aby se klient připojil jen jednou a pak už jen periodicky odesílal data a aby se na server mohlo připojit více klientů. Díky.

    Odpovědi

    8.11.2010 15:24 Michal Kubeček | skóre: 71 | Luštěnice
    Rozbalit Rozbalit vše Re: sockety a c++
    To je spíš na článek než na odpověď do poradny…
    8.11.2010 15:36 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Tak já to trochu upřesním: Jaký režim socketů použít (blokovací x neblokovací), udělat server jedno nebo více vláknový. Tak aby impementace byla co nejednoduší a fungovalo to:-).
    8.11.2010 16:06 miso | skóre: 36 | blog: iSCSI_initiator_howto | Praha
    Rozbalit Rozbalit vše Re: sockety a c++
    Idealne blokovaci a viacvlaknovy. Z dotazu ale nie je jasne, comu presne nerozumies - potrebujes poradit s dokumentaciou?
    Project Satan infects Calculon with Werecar virus
    8.11.2010 16:32 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Projíždím si příklady se z http://www.builder.cz/serial147.html a http://www.root.cz/serialy/sokety-a-cc/ a není mi jasné jak udělat, aby ten klient posílal data v nějakém zadaném intevalu tomu serveru, připojil se pouze na začátku (connect) a pak už jen pomocí send a recv komunikoval se serverem. Např. aby mu každou minutu poslal nějaké číslo a server mu potvrdil příjem a vytiskl ho do konzole.
    8.11.2010 18:54 rastos | skóre: 63 | blog: rastos
    Rozbalit Rozbalit vše Re: sockety a c++
    není mi jasné jak udělat, aby ten klient posílal data v nějakém zadaném intevalu tomu serveru
    Pýtaš sa, ako zariadiť, aby program nejakú dobu nerobil nič?

    sleep
    , připojil se pouze na začátku (connect) a pak už jen pomocí send a recv komunikoval se serverem.
    Vyrobíš socket, dostaneš handle, a ten budeš používať po celú dobu behu programu.

    Ak ti to pripadá, ako blbá odpoveď, tak to bude tým, ako bola položená otázka. Skús si svoju otázku prečítať so odstupom a z pohľadu niekoho, kto nevie čo riešiš a nevie ani či zápasíš s kompiláciou, alebo hľadáš nejakú knižnicu, alebo nevieš aké funkcie použiť, ....
    8.11.2010 19:56 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Omlouvám se za blbě položený dotaz. Já jsem se v tom kompletně ztratil. Přidávám zdrojáky klienta a servera. V tomto případě se klient připojí, odešle pozdrav serveru, přijme pozdrav od serveru a odpojí se. Server takto obslouží tři klienty ukončí se. A mně jde o to jak udělat aby se ten klient připojil, zůstal připojený a každou minutu poslal serveru ten pozdrav a přijal odpověd. Snad je to už jasné.:-) Díky moc.

    klient:
    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <string>
    #include <unistd.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <cstring>
    
    
    
    #define BUFSIZE 1000
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        std::string text("Ahoj\n"); // Odesilany a prijimany text
        hostent *host;              // Vzdaleny pocitac
        sockaddr_in serverSock;     // Vzdaleny "konec potrubi"
        int mySocket;               // Soket
        int port;                   // Cislo portu
        char buf[BUFSIZE];          // Prijimaci buffer
        int size;                   // Pocet prijatych a odeslanych bytu
        if (argc != 3)
        {
            cerr << "Syntaxe:\n\t" << argv[0]
                 << " " << "adresa port" << endl;
            return -1;
        }
        port = atoi(argv[2]);
        // Zjistime info o vzdalenem pocitaci
        if ((host = gethostbyname(argv[1])) == NULL)
        {
            cerr << "Spatna adresa" << endl;
            return -1;
        }
        // Vytvorime soket
        if ((mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
        {
            cerr << "Nelze vytvorit soket" << endl;
            return -1;
        }
        // Zaplnime strukturu sockaddr_in
        // 1) Rodina protokolu
        serverSock.sin_family = AF_INET;
        // 2) Cislo portu, ke kteremu se pripojime
        serverSock.sin_port = htons(port);
        // 3) Nastaveni IP adresy, ke ktere se pripojime
        memcpy(&(serverSock.sin_addr), host->h_addr, host->h_length);
        // Pripojeni soketu
        if (connect(mySocket, (sockaddr *)&serverSock, sizeof(serverSock)) == -1)
        {
            cerr << "Nelze navazat spojeni" << endl;
            return -1;
        }
        // Odeslani dat
        if ((size = send(mySocket, text.c_str(), text.size() + 1, 0)) == -1)
        {
            cerr << "Problem s odeslenim dat" << endl;
            return -1;
        }
        cout << "Odeslano " << size << endl;
        // Prijem dat
        text = "";
        while (((size = recv(mySocket, buf, BUFSIZE - 1, 0)) != -1) && (size != 0))
        {
            cout << "Prijato " << size << endl;
            text += buf;
        }
        // Uzavru spojení
        close(mySocket);
        cout << endl << text << endl;
        return 0;
    }
    
    server:
    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <string>
    #include <unistd.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <cstring>
    
    
    #define BUFSIZE 1000
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
       std::string text;             // Prijimany text
       sockaddr_in sockName;         // "Jmeno" portu
       sockaddr_in clientInfo;       // Klient, ktery se pripojil 
       int mainSocket;               // Soket
       int port;                     // Cislo portu
       char buf[BUFSIZE];            // Prijimaci buffer
       int size;                     // Pocet prijatych a odeslanych bytu
       socklen_t addrlen;            // Velikost adresy vzdaleneho pocitace
       int count = 0;                // Pocet pripojeni
    
       if (argc != 2)
       {
         cerr << "Syntaxe:\n\t" << argv[0]
    	  << " " << "port" << endl;
         return -1;
       }
       port = atoi(argv[1]);
       // Vytvorime soket - viz minuly dil
       if ((mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
       {
         cerr << "Nelze vytvorit soket" << endl;
         return -1;
       }
       // Zaplnime strukturu sockaddr_in
       // 1) Rodina protokolu
       sockName.sin_family = AF_INET;
       // 2) Cislo portu, na kterem cekame
       sockName.sin_port = htons(port);
       // 3) Nastaveni IP adresy lokalni sitove karty, pres kterou je mozno se
       //    pripojit. Nastavime moznost pripojit se odkudkoliv. 
       sockName.sin_addr.s_addr = INADDR_ANY;
       // priradime soketu jmeno
       if (bind(mainSocket, (sockaddr *)&sockName, sizeof(sockName)) == -1)
       {
         cerr << "Problem s pojmenovanim soketu." << endl;
         return -1;
       }
       // Vytvorime frontu pozadavku na spojeni. 
       // Vytvorime frontu maximalni velikosti 10 pozadavku.
       if (listen(mainSocket, 10) == -1)
       {
         cerr << "Problem s vytvorenim fronty" << endl;
         return -1;
       }
       do
       {
         // Poznacim si velikost struktury clientInfo.
         // Predam to funkci accept. 
         addrlen = sizeof(clientInfo);
         // Vyberu z fronty pozadavek na spojeni.
         // "client" je novy soket spojujici klienta se serverem.
         int client = accept(mainSocket, (sockaddr*)&clientInfo, &addrlen);
         int totalSize = 0;
         if (client == -1)
         {
           cerr << "Problem s prijetim spojeni" << endl;
           return -1;
         }
         // Zjistim IP klienta.
         cout << "Nekdo se pripojil z adresy: " 
    	  << inet_ntoa((in_addr)clientInfo.sin_addr) << endl;
         // Prijmu data. Ke komunikaci s klientem pouzivam soket "client"
         text = "";
         // Prijmeme maximalne 6 bytovy pozdrav. 
        while (totalSize != 6)
        //{
           if ((size = recv(client, buf, BUFSIZE - 1, 0)) == -1)
           {
    	 cerr << "Problem s prijetim dat." << endl;
    	 return -1;
           }
           cout << "Prijato: " << size << endl;
           totalSize += size;
           text += buf;
        }
         cout << text << endl;
         // Odeslu pozdrav
         if ((size = send(client, "Nazdar\n", 8, 0)) == -1)
         {
           cerr << "Problem s odeslenim dat" << endl;
           return -1;
         }
         cout << "Odeslano: " << size << endl;
         // Uzavru spojeni s klientem
        close(client);
       }
       while (++count != 3);
       cout << "Koncim" << endl;
       close(mainSocket);
       return 0;
    }
    
    8.11.2010 20:34 rastos | skóre: 63 | blog: rastos
    Rozbalit Rozbalit vše Re: sockety a c++
    Na strane klienta je to jednoduché
    for (;;)
    {
     // Odeslani dat
        if ((size = send(mySocket, text.c_str(), text.size() + 1, 0)) == -1)
        {
            cerr << "Problem s odeslenim dat" << endl;
            return -1;
        }
        cout << "Odeslano " << size << endl;
        // Prijem dat
        text = "";
        while (((size = recv(mySocket, buf, BUFSIZE - 1, 0)) != -1) && (size != 0))
        {
            cout << "Prijato " << size << endl;
            text += buf;
        }
        sleep(5);
    }
    
    Na strane servera tiež môžeš jednoducho urobiť loop, ktorý ide do nekonečna a postupne bude obsluhovať klientov. Ak by mal obsluhovať viacero klientov naraz, je to trocha komplikovanejšie. Ak si dobre spomínam, tak server čaká v accept(). Keď sa klient pripojí, tak accept() prejde a klient sa môže baviť so serverom, ale zároveň môžeš znova vykonávať accept(). Napr. v inom threade.
    9.11.2010 00:18 asi si ten profil uz vazne zalozim
    Rozbalit Rozbalit vše Re: sockety a c++

    Pokusim se ten server vyjadrit kusem pseudokodu, berte to prosim s rezervou.V realu se krome chybovych stavu musi take zpracovat zavrena spojeni (preskladat sadu descriptoru apod.). Thready bych radil rozhodne nepouzivat.

    Btw nechcete v tomto pripade pouzit radsi UDP? Bylo by to podstatne jednodussi s totoznym vysledkem (pouze s rizikem sem tam ztraceneho UDP datagramu)

    PS: U TCP bych v klientovi doporucoval nespolehat se na to, ze se vsechna data podari odeslat naraz na jeden send.

    cokoli set_nonblock(int fd)
    { // man fcntl
      int flags = fcntl(fd, F_GETFL, 0);
      fcntl(fd, F_SETFL, O_NONBLOCK | flags);
      // v realu vsude kontrolovat navratove hodnoty
      // throw, return atd.
    }
    ...
    server = socket, set_nonblock, bind, listen
    ...
    // man poll
    // google poll example
    ...
    vlozit_do_poll_sady(server); // na prvni misto
    ...
    while (furt)
    {
      vynuluj a nastav (r)eventy v cele sade;
      poll(...);
      prvek = prvni_v_sade;
      if ( POLLIN == (POLLIN & prvek->revents) )
      { // mame prichozi spojeni
        novy_socket = accept(prvek->fd, ...);
        ...
        set_nonblock(novy_socket);
        vlozit_do_poll_sady(novy_socket);
      }
      for (prvek = dalsi_v_sade; az_do_konce)
        if ( POLLIN == (POLLIN & prvek->revents) )
          proved_read(prvek->fd);
    }
    
    9.11.2010 14:40 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Díky za ten pseudokód, pomohlo mi to:-). Ještě jsem se chtěl zeptat jak by šlo zajistit, aby klient a server komunikovali šifrovaně (např. přes SSH tunel). Díky
    9.11.2010 14:49 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Teď asi míchám jabka s hruškama:-[
    9.11.2010 15:32 Michal Kubeček | skóre: 71 | Luštěnice
    Rozbalit Rozbalit vše Re: sockety a c++
    Pokud to chcete řešit přímo v aplikaci, použijte OpenSSL. Pokud mimo ni, tak třeba stunnel.
    9.11.2010 18:02 asi si ten profil uz vazne zalozim
    Rozbalit Rozbalit vše Re: sockety a c++

    Implementace pomoci OpenSSL neni uplne trivialni zalezitost, pokud to ma fungovat spravne (osetrovat vsechny stavy, provest SSL handshake, renegociace apod.).

    Uplne nejjednodussi reseni by bylo pustit server aplikaci na serveru na localhostu, z klienta (stroje) udelat SSH tunel na server a klientskou aplikaci se pripojovat na tento tunel. Napr. (opet s rezervou)

    server:

    # server_app --addr 127.0.0.1 --port 9999

    klient:

    # ssh -N -L localhost:1234:localhost:9999 server
    # client_app --addr 127.0.0.1 --port 1234

    10.11.2010 13:20 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    Díky všem za pomoc. Ještě bych se chtěl zeptat, jestli nějak jde přímo v c++ přistupovat k informacím jako je teplota cpu a hdd, otáčky větráčků, spuštěné procesy atd. Zatím je čtu tak že přes fci systém() ukládám do textového souboru a tak pak zpracovávám. Díky
    10.11.2010 13:43 Messa | skóre: 39 | blog: Messa
    Rozbalit Rozbalit vše Re: sockety a c++
    Přes fci system() spouštíš jen další program, který je nejspíš opět v C a něco dělá. Takže to něco můžeš dělat rovnou ty :) Typicky se na Linuxu jedná o čtení odněkud z /proc nebo /sys, protože přímo na hardware si z userspace sáhnout pochopitelně nemůžeš.
    10.11.2010 14:37 pedraz
    Rozbalit Rozbalit vše Re: sockety a c++
    V té fci system() spouštím bashovské příkazy a přesměrovávám je do toho texťáku. Právě té práci s tím texťákem bych se chtěl vyhnout tak, že bych ty údaje doloval přímo v c a ukládal je rovnou do proměných.
    10.11.2010 14:48 Denwerko | skóre: 2
    Rozbalit Rozbalit vše Re: sockety a c++
    hmm... a nebolo by lepšie vynechať ukladanie do textoveho suboru a namiesto toho pomocou fork, pipe, execve ( napr ) dostať vystup tych prikazov ?

    no offence, čisto teoreticky...

    Založit nové vláknoNahoru

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

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