send() ne zagotavlja, da bo poslal celotno sporočilo do prejemnika. za to moraš ti poskrbet. Preveri koliko bajtov je že poslano in od tega lahko prečitaš koliko jih še moraš poslat. Enako velja za recv(). Sproti preverjaj koliko si že sprejel.
Ta funkcija na server side proži signal readyRead(), ki je povezan s slotom receiveMessage(). V tem slotu že preverjam količino prejetih bytov. Če v ta slot postavim števec ugotovim, da se slot sploh ne sproži tolikokrat kot mi client pošlje sporočillo. Sedaj ne vem, ali client teh sporočil sploh ne pošlje ali se kje izgubijo ali pa jih server ne prestreže. Naj omenim še, da client in server tečeta trenutno na istem računalniku, tako da ni neke bojazni za packet lost.
Še to... V clientu zgornja funkcija (write) vrača število poslanih bytov. In to število se ujema z velikostjo dejanskega (QByteArray) sporočila. Iz tega lahko sklepam, da sporočilo dejansko je poslano.
Na spodnjem linku je tcpdump (oz. screenshot wireshark-a) v primeru, ko sem iz clienta poslal 10 sporočil, na server pa sem prejel samo eno. Če sem čisto odkrit, mi izpis ne pove kaj dosti razen tega, da je client dejansko poslal 10 sporočil, ter to da me moti v izpisu "TCP CHECKSUM INCORRECT". Prosim te, če si tako dober in si pogledaš izpis. Mogoče bo tebi kaj več jasno
zgleada vse vredu, client pošlje 10 paketov in server vseh 10 potrdi. tist crc error lahk ignoriraš ker se pravi crc ustvari na hardwerskem nivoju in wireshark ne more dobiti prej pravega crc-ja. drugače pa nevem. na tem nivojem zgleda vse ok.
Problem tiči v tem, da sama write() funkcija ne pošlje podatkov direktno "na kabel" ampak jih preda kernelu (logično). Če ti podatki prihajajo do kernela prehitro (brez pavze), se jih ta odloči združiti in jih poslati v enem kosu. Tega nisem predvidel (tako kot pri TrollTechu tega niso omenili nikjer v dokumentaciji).
Malenkost sem spremenil ServerThread::receiveMessage() (upoštevajoč zgoraj napisano) in stvar deluje.
Celotna rešitev je tukaj (če se bo slučajno kdo srečal s podobnim primerom).
sicer se to lahko delno popravi. lahko ročno povečaš send buffer. send buffer se lahko napolni že ob enkratnem klicu, če so padatki preveliki za njega. v tem primeru send() vrnne manjšo velikost poslanih bajtov kot jih ti zahtevaš ob klicu.
Komentarji
Jaz v clientu uporabim
qint64 QIODevice::write ( const QByteArray & byteArray )
Ta funkcija na server side proži signal readyRead(), ki je povezan s slotom receiveMessage(). V tem slotu že preverjam količino prejetih bytov. Če v ta slot postavim števec ugotovim, da se slot sploh ne sproži tolikokrat kot mi client pošlje sporočillo. Sedaj ne vem, ali client teh sporočil sploh ne pošlje ali se kje izgubijo ali pa jih server ne prestreže. Naj omenim še, da client in server tečeta trenutno na istem računalniku, tako da ni neke bojazni za packet lost.
Še to... V clientu zgornja funkcija (write) vrača število poslanih bytov. In to število se ujema z velikostjo dejanskega (QByteArray) sporočila. Iz tega lahko sklepam, da sporočilo dejansko je poslano.
Hvala
Še link
Problem tiči v tem, da sama write() funkcija ne pošlje podatkov direktno "na kabel" ampak jih preda kernelu (logično). Če ti podatki prihajajo do kernela prehitro (brez pavze), se jih ta odloči združiti in jih poslati v enem kosu.
Tega nisem predvidel (tako kot pri TrollTechu tega niso omenili nikjer v dokumentaciji).
Malenkost sem spremenil ServerThread::receiveMessage() (upoštevajoč zgoraj napisano) in stvar deluje.
Celotna rešitev je tukaj (če se bo slučajno kdo srečal s podobnim primerom).
Hvala za pomoč!