www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Winsock in GPRS
Pojdi na stran Prejšnja  1, 2
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Programska oprema
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Pon Jun 19, 2006 10:24 pm    Naslov sporočila:   Odgovori s citatom

Kaj vrne funkcija niti nisem gledal, ker sem sever samo predelal iz neke delujoče rešitve. Bom pa še malo predelal program po tvojih priporočilih. Prej niti nisem vedel, če funkcija pošlje vrednost 0x00, ampak glede na to da nikjer ne piše da je ne pošlje jo verjetno bo poslal.

Sedaj pa mislim, da je večino napak že odkritih, tako da bojo verjetno kmalu odpravljene. Če odkriješ še kaj, nimam nič proti temu da mi poveš. Wink

Bom po teh popravkih tudi objavil gor server in client aplikacijo. Ta client pa je bil narejen predvsem za testiranje serverja, ker je tapravi client GSM naprava.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Tor Jun 20, 2006 9:18 am    Naslov sporočila:   Odgovori s citatom

Sem popravil nekatere napake. Namesto strlen sem uporabil strnlen, dodal sem pošiljanje terminacijskega znaka ('\0') ter malo bolj opazno naredil izračun dolžine podatkov (prej je bil strlen v funkciji send sedaj pa je pred funkcijo in v funkcijo vpišem samo število bajtov za poslat).

Kot sem obljubil prilagam server.cpp in client.cpp. Sta pa ta programa narejena za UDP protokol.



Server.cpp
 Opis:

Download
 Ime datoteke:  Server.cpp
 Velikost datoteke:  5.26 KB
 Downloadano:  11 krat


Client.cpp
 Opis:

Download
 Ime datoteke:  Client.cpp
 Velikost datoteke:  3.84 KB
 Downloadano:  0 krat

Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.52

PrispevekObjavljeno: Tor Jun 20, 2006 10:55 am    Naslov sporočila:   Odgovori s citatom

Hm, v server.cpp vidim nekaj reci, ki so ocitno posledica tvoje predelave obstojecega primera in integracije tvojih dodatkov, bolj specificno: opazam, da je originalna koda ze delovala pravilno (je ze vrnila kolicino prejetih podatkov), ti si pa po nepotrebnem kompliciral z str*len(). Vrednost je v spremenljivki nRet in mora znasati tocno stevilo sprejetih bajtov (= vrednost, ki jo isces in za katero po nepotrebnem klices dodatno funkcijo), ne glede na terminacijo (ob uporabi terminacije bo seveda en znak vec, saj posljes tudi terminator sam). Koda ze prej preveri ali je prislo do napake, tako da je ta aspekt pokrit.

Prav tako ni potrebno prebrskati celotnega bufferja za tvoj magic number ("#"), ampak je dovolj iskanje do nRet - 1, ce je nRet > 0 (kar mora biti, sicer skoci koda ze zgoraj ven iz glavne zanke). Zdaj tudi razumem zakaj si napisal, da se v bufferju "pojavljajo eni nakljucni znaki" - to se zgodi zato, ker je tudi omenjeno iskanje po celotnem bufferju tvoja napaka; ce bi preiskal samo dejansko prejete podatke, do tezave seveda ne bi prislo.

Nekoliko nizje vrstica

szBuf[nRet]=0;

sluzi temu, da ni potrebno posiljati terminacijskega znaka za znakovni niz (\0), prej pa ti ni pomagala ravno zaradi tvojega buga, omenjenega v prejsnjem odstavku (jaz sem zadnjic predpostavil, da je program sicer napisan pravilno). To dodajanje 0x00 po sprejemu prihrani prenos enega bajta - ce gre za veliko kolicino malih paketkov, je lahko prihranek kar opazen, zato je tovrstno pocetje bolj smiselno kot posiljanje terminatorja, dokler se zavedas omejitev (ne smes postali vec kot N - 1 znakov, kjer je N dolzina bufferja).

V glavnem ... cel kup nepotrebnega kompliciranja in tezav, ki jih lahko elegantno odpravis, pa se koda bo bolj ucinkovita. Vrzi ven tisto traparijo z dolzino stringa, namesto buflen podaj nRet (kar je vrednost, ki jo isces), preverjaj samo vsebuno bufferja od 0 do nRet - 1 (pri tvoji obliki pogoja zamenjaj i z nRet) in dodaj nekaksen error/exception handling za takrat, ko pride do nepredvidenega primera.

Cisto zares ti bo pomagalo, ce si izposodis prej omenjeno knjigo in preberes vsaj osnovna poglavja - ce bi to naredil takoj, ne bi sploh vpeljeval toliko problemov v svoj izdelek Wink
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Tor Jun 20, 2006 11:41 am    Naslov sporočila:   Odgovori s citatom

Zgleda da moram še malo opisati moj protokol pošiljanja podatkov (bi ga verjetno moral opisati že prej, da ne bi prihajalo do podobnih nesporazumov).

Naprava se najprej pošlje na server podatke v obliki: "<tekst>#<checksum>"
Potem server ta podatek pregleda, da vidi, če je tekst pravilne oblike ("<tekst>#<checksum>") in če se <checksum> ujema z izračunanim. Glede na prejšen rezultat pošlje nazaj v napravo tekst "\r\nOK\r\n" oz. "\r\nERROR\r\n".

Še na kratko: server prejme podatek, ga preveri in pošlje potrditev.

Trenutno naprava še ne pošilja terminacijskega znaka, zato je potreben tisti szBuf[nRet]=0; (tudi ko bo, verjetno ne bi bilo slabo to obdržati, saj tako zagotoviš da je v vsakem primeru na koncu terminacija).
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.52

PrispevekObjavljeno: Tor Jun 20, 2006 12:35 pm    Naslov sporočila:   Odgovori s citatom

Terminacija ne bo potreba, ce popravis kodo tako, kot sem napisal zgoraj (uporabljaj nRet, ki ga vrne recvfrom()).

Vse, kar sem napisal v oprejsnjem sporocilu, drzi tudi zdaj, ko si opisal format poslanih podatkov - ne brskaj po celem bufferju, pa ne bo nobenih tezav, ki bi jih bilo potrebno odpravljati z dodatnim flikanjem lukenj.
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Tor Jun 20, 2006 12:58 pm    Naslov sporočila:   Odgovori s citatom

Verjetno z brskanjem misliš na ta for stavek:
Koda:
         for(i=0; i<255; i++)
         {
            if(szBuf[i]==0)   //// če v stringu ni bilo znaka '#' zavrni sprejet podatek
            {
               k=0;
               chksum=1;
               break;
            }//end if

            if(szBuf[i]=='#')
            {
               k=3;
               break;
            }//end if
            chksum += szBuf[i];
         }//end for


Prvi if preveri, če se pred znakom '#' pojavi '\0'. To pomeni da je oblika prejetega podatka napačna, ker ne vsebuje znaka '#', ki loči podatke od checksuma.

Drugi if pa poskrbi, da se izračuna checksum za podatke do znaka '#'. Če se je for zanka zaključila, ko je prišla do znaka '#', potem se še prebere vrednost, ki je za tem znakom in ta vrednost je checksum. Ko imam oba checksuma ju primerjam in na podlagi tega potem pošljem potrditev.

V sami kodi ne vidim več nobenega buga in tudi ne flikanja lukenj.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.52

PrispevekObjavljeno: Tor Jun 20, 2006 2:18 pm    Naslov sporočila:   Odgovori s citatom

Kot sem ti ze prej napisal, je napaka v tem, da preverjas vsebino celotnega bufferja, ne glede na to, koliko znakov si dejansko sprejel. Sprejel si nRet znakov, zato je potrebno preveriti le pozicije od 0 do nRet - 1.

Tvoja koda spodaj pod prvo vrstico citiranega dela (iskanje terminacijskega znaka) je samo posledica omenjene napake - ce luknje ne bi bilo, je ne bi bilo potrebno dodatno popravljati, zato je boljse, da napako odpravis, kot pa da "zdravis" simptom. Ce ne vidis tezave v tem izseku, potem bos imel bistveno vecje probleme, ko bos prisel do obseznejse kode, ki ne bo tako lahko odpuscala malomarnosti (glej M$ Windows).
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Tor Jun 20, 2006 2:32 pm    Naslov sporočila:   Odgovori s citatom

No to pa sem spregledal (i<255 v for zanki) in bom popravil, ampak jaz moram pregledati buffer, ker edino tako izvem, če string vsebije '#' in ko ga najde gre ven iz for zanke, če pa namesto znaka '#' najde '\0' potem ugotovi, da je string napačne oblike in gre tudi ven iz for zanke. Tako da "it's not a bug, it's a feature". Very Happy
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.52

PrispevekObjavljeno: Tor Jun 20, 2006 2:50 pm    Naslov sporočila:   Odgovori s citatom

Znaka \0 ne bos nasel, ce ga prej tja sam ne postavis, postavis pa ga na mesto nRet v bufferju (torej dolzian + 1). Ce bi pregledal samo nRet znakov (namesto 255), ne bi \0 nikoli nasel, ce je nikoli ne posljes in ce ne pride do napak pri prenosu. V tem primeru niti ni potrebno postavljati terminacijskega znaka, saj ne sluzi nicemur vec.

To, da bi rad nasel "#", mi je jasno, zato sem tudi ze prej ustrezno oblikoval moje odgovore - ce naredis tako, kot sem napisal ze nekaj sporocil nazaj, bo delalo ravno tako, kot ti to pricakujes, ne bo pa nobenih bugov in neucinkovitosti v izvedbi.
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Tor Jun 20, 2006 3:07 pm    Naslov sporočila:   Odgovori s citatom

V for zanki je sedaj že 255 popravljen v nRet.

\0 pa je potreben, ker ko grem iz for zanke dobim lokacijo prve cifre checksuma, ki je za '#' in to potem pretvorim v int s funkcijo atoi ( rcvchksum=atoi(&szBuf[i+1]); )

Se ti pa še enkrat zahvaljujem za vso pomoč pri odkrivanju napak.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Sre Jun 21, 2006 9:35 am    Naslov sporočila:   Odgovori s citatom

Sokrat, mogoče veš zakaj funcija recvfrom() neha delati, ko v for zanki uporabim nRet? (nRet je int, zato sem tudi i spremenil iz char v int)

Funkcija se takoj vrne z nekim errorjem in to samo takrat, ko dam v for zanko nRet, ko pa to spremenim nazaj v 255 pa spet dela.

(Server sedaj že 9,5 ur dela brez problem s tem da vsako minuto pošljem en telegram iz naprave na server.)
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Sokrat
Član
Član



Pridružen-a: Čet 25 Avg 2005 11:00
Prispevkov: 5584
Aktiv.: 23.52

PrispevekObjavljeno: Sre Jun 21, 2006 10:51 am    Naslov sporočila:   Odgovori s citatom

Ni mi najbolj jasno kaj ti ne deluje - uporabi debugger in spremljaj stanje spremenljivk ter tok programa, da vidis kje pride do napake oz. do nepravilnega poteka.

Ce si samo spremenil

for(i=0; i<255; i++)

v

for(i = 0; i =< nRet; i++)

potem ne vidim razloga zakaj ne bi delovalo.

Za primerjavo bi sploh lahko uporabil funkcijo iz knjiznice (npr. memcmp() ali katero od funkcij za iskanje po stringih, katerih je kar nekaj), namesto teh komplikacij.
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Djurodrljaca
Član
Član



Pridružen-a: Pet 19 Dec 2003 16:31
Prispevkov: 393
Aktiv.: 1.66
Kraj: Mengeš

PrispevekObjavljeno: Sre Jun 21, 2006 11:22 am    Naslov sporočila:   Odgovori s citatom

Problem je bil v tem, da sem na začetku programa uporabljal listenSocket, potem pa je bil nekje pred recvfrom() deklariran SOCKET remoteSocket in sem potem uporabljal remoteSocket in ne listenSocket. Sedaj ko sem to popravil pa dela tudi z nRet v for zanki. Še ena napaka zaradi predelave različnih verzij serverja ter seveda površnosti. Brick wall

Zelo čudno mi je pa to, da mi je server sploh delal na ta način.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Programska oprema Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran Prejšnja  1, 2
Stran 2 od 2

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 6 dni


Powered by phpBB © 2001, 2005 phpBB Group