Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
mival
Založen: 28. 08. 2010 Příspěvky: 85
|
Zaslal: 6. říjen 2011, 15:19:49 Předmět: |
|
|
Tak mi prosim aspon reknete zda je na to funkce, nebo musim neco vymyslet ja. (kdyz pouzivam vlakna) |
|
Návrat nahoru |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 6. říjen 2011, 20:51:24 Předmět: |
|
|
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 |
|
 |
VladR
Založen: 30. 07. 2007 Příspěvky: 1322 Bydliště: Greater New York City Area
|
Zaslal: 7. říjen 2011, 05:07:53 Předmět: |
|
|
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 |
|
 |
satik
Založen: 06. 05. 2010 Příspěvky: 161 Bydliště: Krkonose
|
Zaslal: 7. říjen 2011, 06:05:50 Předmět: |
|
|
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...  |
|
Návrat nahoru |
|
 |
Houp
Založen: 28. 07. 2007 Příspěvky: 672
|
Zaslal: 7. říjen 2011, 10:39:53 Předmět: |
|
|
satik napsal: |
vybouchne ti to...  |
ale když to vybouchne, tak vyrobil "dynamit" , zkus lepší příklad _________________
 |
|
Návrat nahoru |
|
 |
satik
Založen: 06. 05. 2010 Příspěvky: 161 Bydliště: Krkonose
|
Zaslal: 7. říjen 2011, 11:08:21 Předmět: |
|
|
Houp napsal: |
satik napsal: |
vybouchne ti to...  |
ale když to vybouchne, tak vyrobil "dynamit" , zkus lepší příklad |
Kazdej kdo vyrabi dynamit nechce bejt roztrhanej na kusy
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  |
|
Návrat nahoru |
|
 |
mival
Založen: 28. 08. 2010 Příspěvky: 85
|
Zaslal: 7. říjen 2011, 17:07:03 Předmět: |
|
|
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 |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 7. říjen 2011, 17:56:00 Předmět: |
|
|
Použij non-blocking socket (tzn. bez vláken). _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Weny Sky

Založen: 28. 07. 2007 Příspěvky: 241
|
Zaslal: 7. říjen 2011, 19:19:44 Předmět: |
|
|
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 |
|
 |
mival
Založen: 28. 08. 2010 Příspěvky: 85
|
Zaslal: 7. říjen 2011, 19:34:53 Předmět: |
|
|
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 |
|
 |
mival
Založen: 28. 08. 2010 Příspěvky: 85
|
Zaslal: 7. říjen 2011, 19:38:47 Předmět: |
|
|
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 |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 7. říjen 2011, 20:33:12 Předmět: |
|
|
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 |
|
 |
mival
Založen: 28. 08. 2010 Příspěvky: 85
|
Zaslal: 8. říjen 2011, 07:41:17 Předmět: |
|
|
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.
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 |
|
 |
if.then
Založen: 13. 04. 2008 Příspěvky: 579
|
Zaslal: 8. říjen 2011, 10:28:31 Předmět: |
|
|
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 |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 8. říjen 2011, 13:35:10 Předmět: |
|
|
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 |
|
 |
|