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 18:11 | Zajímavý software

    Nazdar! je open source počítačová hra běžící také na Linuxu. Zdrojové kódy jsou k dispozici na GitHubu. Autorem je Michal Škoula.

    Ladislav Hagara | Komentářů: 0
    dnes 16:55 | Nová verze

    Po více než třech letech od vydání verze 1.4.0 byla vydána nová verze 1.5.0 správce balíčků GNU Guix a na něm postavené stejnojmenné distribuci GNU Guix. S init systémem a správcem služeb GNU Shepherd. S experimentální podporou jádra GNU Hurd. Na vývoji se podílelo 744 vývojářů. Přibylo 12 525 nových balíčků. Jejich aktuální počet je 30 011. Aktualizována byla také dokumentace.

    Ladislav Hagara | Komentářů: 1
    dnes 15:44 | Zajímavý software

    Na adrese gravit.huan.cz se objevila prezentace minimalistického redakčního systému GravIT. CMS je napsaný ve FastAPI a charakterizuje se především rychlým načítáním a jednoduchým ukládáním obsahu do textových souborů se syntaxí Markdown a YAML místo klasické databáze. GravIT cílí na uživatele, kteří preferují CMS s nízkými nároky, snadným verzováním (např. přes Git) a možností jednoduchého rozšiřování pomocí modulů. Redakční

    … více »
    2012 | Komentářů: 0
    dnes 12:55 | Zajímavý software

    Tým Qwen (Alibaba Cloud) uvolnil jako open-source své modely Qwen3‑TTS pro převádění textu na řeč. Sada obsahuje modely VoiceDesign (tvorba hlasu dle popisu), CustomVoice (stylizace) a Base (klonování hlasu). Modely podporují syntézu deseti různých jazyků (čeština a slovenština chybí). Stránka projektu na GitHubu, natrénované modely jsou dostupné na Hugging Face. Distribuováno pod licencí Apache‑2.0.

    NUKE GAZA! 🎆 | Komentářů: 0
    dnes 01:11 | Nová verze

    Svobodný citační manažer Zotero (Wikipedie, GitHub) byl vydán v nové major verzi 8. Přehled novinek v příspěvku na blogu.

    Ladislav Hagara | Komentářů: 0
    včera 16:55 | Nová verze

    Byla vydána verze 1.93.0 programovacího jazyka Rust (Wikipedie). Podrobnosti v poznámkách k vydání. Vyzkoušet Rust lze například na stránce Rust by Example.

    Ladislav Hagara | Komentářů: 0
    včera 14:00 | Komunita

    Svobodný operační systém ReactOS (Wikipedie), jehož cílem je kompletní binární kompatibilita s aplikacemi a ovladači pro Windows, slaví 30. narozeniny.

    Ladislav Hagara | Komentářů: 8
    včera 11:00 | IT novinky

    Společnost Raspberry Pi má nově v nabídce flash disky Raspberry Pi Flash Drive: 128 GB za 30 dolarů a 256 GB za 55 dolarů.

    Ladislav Hagara | Komentářů: 2
    včera 10:22 | Zajímavý software

    Technologie Skip pro multiplatformní mobilní vývoj, která umožňuje vývojářům vytvářet iOS a Android aplikace z jediné Swift a SwiftUI kódové základny, se s vydáním verze 1.7 stala open source.

    Ladislav Hagara | Komentářů: 6
    včera 03:33 | Zajímavý software Ladislav Hagara | Komentářů: 1
    Které desktopové prostředí na Linuxu používáte?
     (17%)
     (6%)
     (0%)
     (10%)
     (21%)
     (3%)
     (5%)
     (2%)
     (11%)
     (36%)
    Celkem 580 hlasů
     Komentářů: 17, poslední včera 15:24
    Rozcestník

    Dotaz: sockety a c++

    8.11.2010 15:10 pedraz
    sockety a c++
    Přečteno: 840×
    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.