Diskuze: Jak vyskočit z blokovaného čtení ? socket tcp

C++ C a C++ Jak vyskočit z blokovaného čtení ? socket tcp

Avatar
pyrin
Člen
Avatar
pyrin:

Dobrý večer všem, sem si říkal, že bych si tu vyzkoušel TCP klienta, který se připojí na server. Server mi periodicky každých 60s posílá žádost o teplotu. Klient tedy poslouchá v blokovaném čtení na příchozí žádost. Ale narazil jsem na problém, že se spojení může rozpadnout. Tak jsem si na klientovi udělal časovač a s každou odchozí teplotou na server se časovač nastaví na 65s. Pokud někdy dojde do nuly, tak provedu close socketu, počkám 2s a udělám open socketu. Jenže spojení na server se naváže OK a server pošle žádost o teplotu, ale klient tuto žádost nezpracuje, protože zůstal viset v tom původním čtení. Domníval jsem se, že se zavřením socketu opustí i toto blokované čtení, ale bohužel ne. Jak z toho ven ? Děkuji za případné nakopnutí. Jirka.

 
Odpovědět 15.10.2015 19:43
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na pyrin
Martin Dráb:

Ahoj,

nějak tvému popisu problému moc nerozumím, možná by bylo nejlepší ukázat kostru kódu na tom, čemu říkáš klient a server, která řeší právě to navazování spojení a posílání dat.

Pak jsou tam pro mě ještě nějaké podivné věci:

  1. Má smysl udržovat TCP spojení, když víš, že data nebudou chodit často (jen každých cca 60 s troška)?
  2. Nebylo by lepší, kdyby se po každých 60 s server na klienta připojil, získal teplotu a odpojil se (otázka je, zda by nestačilo třeba použít UDP), než tam to spojení pořád držet? Druhá možnost je udělat si chytřejší klienty, kteří budou sami periodicky serveru odesílat informace o teplotě a server jim případně tuto periodu nakonfiguruje podle potřeby... a bude si sám řešit, které údaje o teplotě využije a které ne.

Jinak, se sockety se dá pracovat i asynchronně (asynchronní odesílání a přijímání dat), případně se dá zařídit, abys dostával notifikace o stavu určitého socketu. Ale pochybuju, že tyto vymoženosti lze psát rozumně přenositelně (ledaže by existovala nějaká knihovna).

Nahoru Odpovědět 16.10.2015 0:32
2 + 2 = 5 for extremely large values of 2
Avatar
pyrin
Člen
Avatar
Odpovídá na Martin Dráb
pyrin:

Ahoj, děkuji za odpověď. Ještě bych to zkusil více popsat. Server poslouchá na TCP portu 10060. Pokud je žádost o spojení, tak spojení realizuje a do otevřeného socketu pošle specifickým protokolem dotaz klientovi, aby mu poslal 128 bajtů dat. Klient to přijme, zapracuje s nějakým jednočipem a vezme těch 128 bajtů dat a pošle je tím specifickým protokolem na server.
Nelze udělat to, že se potom spojení uzavře, protože ztratím možnost cokoliv ze serveru poslat klientovi a čekat třeba 60s u nějakého webového rozhraní na to, abych mohl stisknout tlačítko a poslat klientovi, který není momentálně připojen, nějaký jiný dotaz specifickým protokolem, tak to je nesmysl. Není to nějaký bankovní systém nebo něco, kde člověk může trávit spoustu času a když to náhodou nejde, tak to zkusí za hodinu znovu. Musí to reagovat obratem.

Klient ten tedy osetvře TCPsocket blokovaný a přejde na fukci read ze socketu a protože je blokovaný, tak tam stojí, dokud mu nepřijdou data socketem. Jenže co se stane, když se spojení rozpadne nebo mi server nepošle žádost do třeba 65s ? Tak client předpokládá, že je spojení špatné a zavolá funkci close socket, ta sice uzavře socket, ale protože čtení je voláno ve svém vlákně a v podstatě to stojí ve volání read, tak se z tohoto volání nedostanu. Tak mně napadlo, že nejdříve bych se měl dostat z toho blokovaného read a potom zavřít socket. Jen netuším jak to provézt. Druhé řešení je udělat to v neblokovaném čtení, potom bych měl kdykoliv po zavolání read ze socketu dostat nějakou hodnotu o počtu přijatých bajtů. Zdroják přikládám. Jirka

Ten zdroják jsem přidal do Máš dlohý zdroják, ale nikdo ho tu nevidím. Tak doufám, že se k němu dostaneš. Jirka

Editováno 16.10.2015 8:58
 
Nahoru Odpovědět 16.10.2015 8:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.