.[ ČeskéHry.cz ].
Vícevláknový server a client - potebuji navod
Jdi na stránku Předchozí  1, 2, 3, 4, 5, 6  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
mival



Založen: 28. 08. 2010
Příspěvky: 85

PříspěvekZaslal: 6. říjen 2011, 15:19:49    Předmět: Odpovědět s citátem

Tak mi prosim aspon reknete zda je na to funkce, nebo musim neco vymyslet ja. (kdyz pouzivam vlakna)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 6. říjen 2011, 20:51:24    Předmět: Odpovědět s citátem

Ahoj,
napsal jsem takový set tříd v C++ pro svoje aplikace, který umí celkově obsluhovat kominikaci přes net. Je to do jisté míry multiplatformní (akorát to neřeší endianitu). Kompiluji to v g++, ale myslím, že VC by to taky mělo sežrat. Brzy k tomu přidám tutoriál, jak to používat. Tady najdeš zdrojáky:

https://github.com/KosarJ/Cpp-multiplatform-networking

Jsou tam jakési komentáře v hlavičkách a v kódu, ale není to nic extra. Takže takový lehký návod, jak to použít:
Je to jednovláknové, ale používá to neblokovací režim socketů - takže jestli by ses měl obejít bez vláken.
Samotnou komunikaci ovládáš přes instanci třídy Socket. Má nějaké metody pro připojení k serveru, připojení ke klientovi, odpojení a k posílání dat tam i zpátky. Pak je tam interface SocketListener. Socket může jednomu SocketListeneru posílat info o událostech (příchozí data, připojení, odpojení atd). Je nutné jednou za čas volat metodu onIdle toho Socketu. Vždy když to zavoláš, tak se Socket podívá, jestli se nestalo něco zajímavýho a případně o tom informuje SocketListener.
No a pak je tu SocketPackage - ten obsahuje data, co se posílají. Obsahuje asi deset proměnných (inty, řetězce atd), který když nastavíš a SocketPackage odešleš, tak je můžeš na druhý straně zase po přijetí přečíst. Co jaká proměnná může obsahovat je v komentářích v hlavičce SocketPackage.

No snad jsem to vysvětlil aspoň trochu. Zejtra tam hodím ten tutoriál, jak to používat, tak by ti to mohlo být jasnější. Kdybys měl nějaké otázky, ptej se.

Napiš, co si o tom myslíš (jestli to budeš používat, jestli to je moc složitý apod). Zatím.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VladR



Založen: 30. 07. 2007
Příspěvky: 1322
Bydliště: Greater New York City Area

PříspěvekZaslal: 7. říjen 2011, 05:07:53    Předmět: Odpovědět s citátem

Taka blba otazka - preco vlastne riesis nieco take komplikovane ? Preco neskusis o triedu menej narocny task ? Stane sa nieco strasne, ak pred dostudovanim zakladnej skoly nebudes mat nakodeny takyto multithreaded server ? Hmm ?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
satik



Založen: 06. 05. 2010
Příspěvky: 161
Bydliště: Krkonose

PříspěvekZaslal: 7. říjen 2011, 06:05:50    Předmět: Odpovědět s citátem

Souhlasim s ostatnima, vrhni se pro zacatek na neco jednoduzsiho, to je jako by ses zacal treba ucit chemii, naucil se vlastnosti par sloucenin a pokousel se namichat dynamit (aniz bys znal jeho slozeni)..., v lepsim pripade to proste jen nebude fungovat a pokud nahodou jo, tak to bude spis katastrofa nez pouzitelne k tomu, k cemu chces, protoze netusis, jak fungujou ruzny reakce mezi chemikaliema a vybouchne ti to... Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Houp



Založen: 28. 07. 2007
Příspěvky: 672

PříspěvekZaslal: 7. říjen 2011, 10:39:53    Předmět: Odpovědět s citátem

satik napsal:
vybouchne ti to... Smile


ale když to vybouchne, tak vyrobil "dynamit" Wink, zkus lepší příklad
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
satik



Založen: 06. 05. 2010
Příspěvky: 161
Bydliště: Krkonose

PříspěvekZaslal: 7. říjen 2011, 11:08:21    Předmět: Odpovědět s citátem

Houp napsal:
satik napsal:
vybouchne ti to... Smile


ale když to vybouchne, tak vyrobil "dynamit" Wink, zkus lepší příklad


Kazdej kdo vyrabi dynamit nechce bejt roztrhanej na kusy Wink

Ja netvrdim, ze se mu to nakonec nepovede nejak splacat, ale i kdyz jo, tak si tim moc nepomuze, kdyz nevi, jak to vsechno funguje - stejne se mu nepovede udelat zbytek, bude mit jen kanal mezi serverem a klientem, kde si bude moct mozna posilat zpravu Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mival



Založen: 28. 08. 2010
Příspěvky: 85

PříspěvekZaslal: 7. říjen 2011, 17:07:03    Předmět: Odpovědět s citátem

Prosiim, jedine co po vas chci je aby jste mi rekli jak mam v consoli zjistit zda mi prisla nova zprava od nektereho clienta aniz by se mi to vzdy zastavilo a cekalo kdy klient napise.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 7. říjen 2011, 17:56:00    Předmět: Odpovědět s citátem

Použij non-blocking socket (tzn. bez vláken).
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Weny Sky



Založen: 28. 07. 2007
Příspěvky: 241

PříspěvekZaslal: 7. říjen 2011, 19:19:44    Předmět: Odpovědět s citátem

mivale, a proc potrebujes zjistit, jestli ti prislo neco nezavisle na preruseni od systemu? Ona ti beztak nedojde zprava driv nez ti system proces odblokuje. Tak jaky to ma duvod?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
mival



Založen: 28. 08. 2010
Příspěvky: 85

PříspěvekZaslal: 7. říjen 2011, 19:34:53    Předmět: Odpovědět s citátem

Weny Sky napsal:
mivale, a proc potrebujes zjistit, jestli ti prislo neco nezavisle na preruseni od systemu? Ona ti beztak nedojde zprava driv nez ti system proces odblokuje. Tak jaky to ma duvod?


Mam pole s uzivately a kotroluji vzdy zda mi ten urcity uzivatel neco nenapsal. Nevim jestli by to slo jinak, protoze jsem nasel jen toto.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mival



Založen: 28. 08. 2010
Příspěvky: 85

PříspěvekZaslal: 7. říjen 2011, 19:38:47    Předmět: Odpovědět s citátem

pouzivam recv(..); a chce to po me socket tak tam dam vzdy sockets[i] (int i v cyklu zvetsuji dokud nedojde na konec vsech uzivatelu.

kód:
      if(sockets.size() != 0)
      {
      for(int i=0; i < sockets.size();i++)
      {      
            answer = recv(sockets[i], message, sizeof(message), NULL);
      strmessage = message;

         cout << "\n"<<strmessage;
   
   
      }

        }
      }
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 7. říjen 2011, 20:33:12    Předmět: Odpovědět s citátem

Takže v první řadě ti doporučuji se úplně vykašlat na myšlenku více vláken (což jsi zřejmě již udělal) - existují jiné a lepší způsoby, jak to řešit.

Takže jestli chceš vědět, proč se to chová tak jak se to chová, přečti si tyto dva články (také tím získáš jasnou představu o tom, jak vlastně tcp networking funguje):
http://www.builder.cz/art/cpp/tcp_klient_windows.html
http://www.builder.cz/art/cpp/tcp_server_windows.html

Pokud neplánuješ nic velkolepějšího než tady uvádíš, doporučuji ti nechat sockety v blokovacím režimu (to je defaultní režim socketů) a použít funkci select. Viz tento článek:
http://www.root.cz/clanky/sokety-a-c-funkce-select/

Také se to dá řešit neblokovacím režimem socketů. V tom případě doporučuji pro pochopení problematiky tento článek:
http://www.root.cz/clanky/sokety-a-c-neblokovaci-rezim-soketu/
a případně se můžeš inspirovat mým kódem (který je odtud stejně obšlehlý):
https://github.com/KosarJ/Cpp-multiplatform-networking/blob/master/SocketWindows.cpp

Snad jsem pomohl. Už si hlavně nestěžuj, že nevíš jak na to. Materiálů tu máš dost a všechny jsou v češtině. Jestli něco nebudeš chápat, klidně se ptej, ale přijď prosímtě s konkrétním dotazem, případě úryvkem kódu, který nechápeš nebo který ti nefunguje.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mival



Založen: 28. 08. 2010
Příspěvky: 85

PříspěvekZaslal: 8. říjen 2011, 07:41:17    Předmět: Odpovědět s citátem

Ahoj, zkusil jsem vytvorit podle jedne te stranky tu podminku ktera zjisti zda od clienta neco prislo, jenze to nefunguje furt jak ma. Dam sem kod kdyby nekdo vydel chybu, ja doufam ze na neco prijdu. Smile

kód:
for(int i=0; i < sockets.size();i++)
      {   
      u_long arg = i+1;
      if(ioctlsocket(sockets[i], FIONREAD , &arg)==SOCKET_ERROR)
      {
         continue;
      }
      else
      {
         answer = recv(sockets[i], message, sizeof(message), NULL);
      strmessage = message;

         cout << "\n"<<strmessage;
   
        }
      }


Funguje to kdyz je pripojen 1 klient. Ale kdyz se pripoji 2 clienti, divne se to strida a skoro vzdy to nejakou zpravu preskoci.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
if.then



Založen: 13. 04. 2008
Příspěvky: 579

PříspěvekZaslal: 8. říjen 2011, 10:28:31    Předmět: Odpovědět s citátem

FIONREAD = počet dat, které může funkce recv() přečíst v jedné iteraci
FIONBIO = nenulová hodnota znamená nastavení do neblokovacího režimu (když klient nic nepošle, recv() vrátí SOCKET_ERROR a WSAGetLastError() vrátí WSAEWOULDBLOCK).
Pochopeno?

BTW: Funkci ioctlsocket můžeš volat jednou pro každý socket, nemusíš to dělat v cyklu (což IMHO program nehorázně zpomalí).
_________________
For guns and glory, go to www.ceske-hry.cz.
For work and worry, execute VC++.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 8. říjen 2011, 13:35:10    Předmět: Odpovědět s citátem

kód:

for(int i=0; i < sockets.size();i++)
{   
      u_long arg = i+1;
      if(ioctlsocket(sockets[i], FIONREAD , &arg)==SOCKET_ERROR)
      {
         cerr << "error setting unblockin mode on socket" << endl;
      }
}

while(1)
{
     char buffer[100];
     for(int i=0; i < sockets.size();i++)
     {
          recv(sockets[i], buffer, sizeof(buffer), NULL);
          cout << "client " << i << ": " << buffer << endl;
     }
}


Pak je třeba ještě ošetřit odpojování klientů a opětovné připojování a tak.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku Předchozí  1, 2, 3, 4, 5, 6  Další
Strana 4 z 6

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna