Recv() v klientovi v client-server aplikaci blokuje program – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Recv() v klientovi v client-server aplikaci blokuje program – C / C++ – Fórum – Programujte.comRecv() v klientovi v client-server aplikaci blokuje program – C / C++ – Fórum – Programujte.com

 

Two
~ Anonymní uživatel
1 příspěvek
27. 3. 2013   #1
-
0
-

Zdravím přítomné.

Píšu client-server aplikaci, doted bylo vše v pohodě, klient poslal požadavek pomocí write(), server ho přijal read(), rozparsoval, zpracoval, vytvořil odpověď. Teď se to ale pokazilo. Když jsem napsal funkci write na server a read na klienta pro poslání odpovědi, tak se program při spuštění zastaví a vypadá to, že klient se zasekne na readu, ale zároveň ani server nezpracovává požadavek. Jakoby se posílal první požadavek a nikdy se nedoposlal.

Když ale z klienta funkci read odstraním, tak server požadavek zase přijme, zpracuje a odešle (akorát ho už nikdo nepřijme).

Kód z klienta:

// sends data
  if((size = write(clientSocket, request.c_str(), request.length())) == -1) {
    printErr(ERR_SEND);
    return ERR_SEND;
  } 

  // recieves data
  while ((size = read(clientSocket, buf, BUFFER_LEN)) != 0) {
    recieved.erase();
    recieved.append(buf, size);

    data = data + recieved;
  }

  // closes a connection
  close(clientSocket);

Kód ze serveru:

if((pid = fork()) == 0) {
      while ((size = read(clientSocket, buf, BUFFER_LEN)) != 0) {
        recieved.erase();
        recieved.append(buf, size);

        request = request + recieved;
      }

      parserInput(request);
      getData();
      parserOutput();

      if((size = write(clientSocket, sendback.c_str(), sendback.length())) == -1) {
        printErr(ERR_SEND);
        return ERR_SEND;
      } 

      close(clientSocket);

    }

Prosím pište jakékoliv návrhy. Snad bude nějaký správný.

Nahlásit jako SPAM
IP: 94.112.85.–
Ovrscout
~ Anonymní uživatel
113 příspěvků
28. 3. 2013   #2
-
0
-

#1 Two
Na první pohled těžko střílet od boku, spíš bych se snažil zjistit co se skutečně děje, tj přidat si ladící výpisy aby bylo jasno kde se program "zastaví" a co skutečně vykonal. Pokud máš možnost dvou počítačů(server,client) tak skusit pomocí programu wireshark kouknout co se kde skutečně po ethernetu odesílá abys měl jistotu.

Obecně bych doporučil použít funkci select pro zjištění zda jsou dostupná data než volat cyklicky read.
(kromně možnosti timeoutu je výhoda i to že se dá dělat select nad více sockety. tj není nutný vícevláknový přístup)
(stejně tak lze select použít nad listen socketem místo přímého volání accept pokud to tak náhodou nemáš)


Nepíšeš jaký je to socket (TCP/UDP) a jestli je to blokující/neblokující.
Nicméně: nemůže se stát že odešleš z clienta write dříve než je nastartován/připraven server? Pak by to zatuhlo na čtení a celý (předpokládám vnější) cyklus by se neopakoval.
Multithreading pomocí fork moc neznám/nepoužívám, nemůže to být problém někde zde? (třeba poradí někdo jiný)

Jinak se pokud to někde měníš, bylo by dobré zkontrolovat správné parametry socketu - (blokující/neblokující,SO_RCVTIMEO,....)

Nahlásit jako SPAM
IP: 178.255.170.–
KIIV
~ Moderátor
+43
God of flame
28. 3. 2013   #3
-
0
-

#2 Ovrscout
fork se pouziva pokud potrebujes vic filedescriptoru nez mas normalne na jeden proces (vcetne vsech threadu) k dispozici - defaultne je to 1024 (a nekolik je hned zabrano na stdin, out, err....) ikdyz nekdy nejsou potreba a daji se pak uvolnit...

kazdopadne pokud bys mel vic klientu, nebo proste hodne souboru a tak, tak se pres ten limit nedostanes jinak nez dalsim procesem... mas jinej proces navesenej na accept + pripadne zamek, aby se neodblokovaly vsechny najednou...

Metoda vlakno per spojeni taky neni dobra vec... obzvlaste pokud zustane thread stack size treba defaultnich 10MB.... par stovek spojeni a pamet je fuc (nedej boze ze se vyrabi threadu nekolik)

Nahlásit jako SPAM
IP: 83.42.11.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Ovrscout
~ Anonymní uživatel
113 příspěvků
29. 3. 2013   #4
-
0
-

#3 KIIV
1024 je cislo kam jsem se zatím nedostal :) tj nepotřeboval jsem to řešit.

Trochu jsem zagooglil a je to opravdu zajímavé téma. - A abych to nezapomněl tak to napíšu sem ačkoliv je to trochu off-topic k původnímu dotazu za což se omlouvám  ale třeba se to někdy někomu také hodí.

Překvapilo mne jak moc se odlišuje (při práci se sockety) windows a linux.Nejen defaultní limity a jejich změna/obcházení, ale hlavně implementace FD_xxx maker. Na linuxu jsou makra mnohem rychlejší ale FD_SETSIZE udává maximální číslo deskriptoru  který lze pro tato makra použít a nejde standardně změnit(a bez toho není nic platný ani vyšší limit povolený systémem).Na windows jsou FD_xxx makra pomalá ale FD_SETSIZE udává na windows počet socketů který tam jde vrazit a navíc jde toto číslo jednoduše měnit(nastavením před vložením winsock.h) a i dafultní systémový limit je zřejmně vyšší. (a počet socketů "asi" není omezen počtem filedeskriptorů v standardní knihovně?)

Podle toho co jsem porůznu našel ale jde limit upravit od jednotek do desítek tisíc(32000?) na obou systémech ačkoliv tam už se to dotýká všeho možného od limitů RAM až po limity implementace síťového stacku, navíc záleží jestli je to spojení odchozí nebo příchozí atd, atd.
V tomto směru to pro windows vypadá jednodušší a snáze lze dosáhnout více socketů - default by měl být vyšší.
Na linuxu je nastavení všelijakých limitů mnohem rozmanitější a tak je mnohem více prostoru k nastavení z hlediska bezpečnosti, ale zase je toho až moc a nenašel jsem snad dva články které by se shodli.Navíc se  zdá že během let vývoje nastali různé změny a tak dopátrat se něčeho obecně použitelného ale přitom s konkrétními čísly je skutečně fuška. Zřejmně by při případné realizaci nezbyla jiná možnost než to prostě na konkrétním systému vyzkoušet.

Nahlásit jako SPAM
IP: 178.255.170.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 91 hostů

Podobná vlákna

Client-server-client — založil MM

Client server c# — založil Misiak

Server + Client — založil Mudraon

[C#] Server client — založil gledy

Client/Server — založil silent

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý