Ovu stranicu je najbolje pregledavati u modernom internet pregledniku s omogućenim JavaScriptom.

[MREPRO] 4. domaća zadaća - 2019/2020

Sashat_Triceps

E kako definirati buffer za primanje RREQ zahtjeva? U specifikacijama kaže 2 bajta za code ( uint_16t), al onda za ime datoteke kaze samo “string” i kasnije isto tako za polje načina prijenosa.
Koliko taj “string” mora biti velik? Jel postoji neki pametniji način od toga da uzmem char polje malo veće duljine i iz njega sa strtok odvojim ime datoteke i način prijenosa?


Gussy

Sasha_Triceps Ne vidim ni u ovom RFC 1350 da igdje piše koliko dugačak mora biti taj string filename, pa stavi tipa 256 ili nešto tako. Mislim da to nije toliko bitno. Za međuispit i za ove labose itd., ja sam radio posebne structove za tipove paketa koji koristim u tom zadatku. Npr. struct za rip paket iz meduispita.

struct rip_entry
{
    unsigned int af_identifier : 16;
    unsigned int route_tag : 16;
    unsigned int ip_address : 32;
    unsigned int subnet_mask : 32;
    unsigned int next_hop : 32;
    unsigned int metric : 32;
};   

struct rip_packet
{
    unsigned int command : 8;
    unsigned int version : 8;
    unsigned int must_be_zero : 16;
    struct rip_entry entries[MAX_ENTRY];
};

Ovi brojevi pored svakog elementa structa se zovu bit field i označavaju koliko bitova zauzima taj element unutar samog structa, ako piše 16, to znači 2 bytea. Nisam siguran ako koristiš bit field za neki element unutar structa, da li onda svi elementi isto moraju koristiti bit fieldove ili mogu biti i elementi za koje nije definirana veličina bitova na ovaj način.
Tj. može li se ovako:

struct foo
{
    int a : 16;
    int b;
}

Po nekoj logici ovaj int a bi bio veličine 2 bajta, a int b bi zauzimao normalnu količinu memorije koliko int zauzima. Pretpostavljam da i ovo radi.


Gussy

Sasha_Triceps Lol sad sam skuzio o cemu pricas i ovaj moj odgovor nema veze s tim, al cu svejedno ostavit. Ionako ne mogu obrisat.
Nisam siguran kako bi se trebalo “odvojiti” taj string od ostatka poruke, tj. skuziti gdje zavrsava.
https://github.com/crossbowerbt/tftpserver/blob/master/tftpserv.c
Ovdje je lik iskoristio \0 da nađe gdje završava filename.


Gussy

Jeste li napravili poseban struct za svaki mogući tip paketa?


Sashat_Triceps

huba buba Hvala ti na dužem odgovoru 🙂
Napravio sam zadaću u međuvremenu, u biti sam puknuo char polje "Data"velicine 100, poslije codea od 2 bajta, pa se onda kasnije drkas sa izvlacenjem file namea i nacina prijenosa. Stvar je u tome sto oni nisu zapravo odvojeni sa tom nulom kao što je u specifikaciji. Kad sam testirao s wiresharkom odvojeni su s \0 , a 0 dolazi tek na kraju paketa, tako daa nez tko tu koga laže . Koristio sam isti delimiter ko taj lik i radi


Gussy

Sasha_Triceps Ocu stici do sutra napisati sve? Ima milijun stvari koje se trebaju implementirati.


Sashat_Triceps

huba buba Pa ovisi koliko si napravio, najviše vremena će ti uzet obrada tekstualne datoteke za \n -ove. Poslije toga ovo ostalo ide glatko


Gussy

Sasha_Triceps Kako si riješio taj problem sa zamjenjivanjem \n sa \r\n jer se ne treba “samo” zamijeniti kako oni kazu nego moras dodati jos jedan znak i onda cijela ta obrada ode u kurac.


Sashat_Triceps

huba buba Učitaš podatke iz filea u neko polje. Zatim u petlji ides bajt po bajt kroz to polje i stavljaš bajtove u buffer za slanje. Kad naiđes na \n , u istoj iteraciji stavi \r zatim \n u buffer.


Gussy

Sasha_Triceps Jel misliš sve podatke iz filea staviti u jedno polje?


Cvija

A kako se postiže konkurentnost?

Jel moram raditi one forkove pa da svako dijete obrađuje svakog klijenta ili postoji neki drugi način?
U TFTP-u u knjizi se spominje neka konkurentnost mijenjanjem portova prilikom slanja paketa


Sashat_Triceps

Cvija Sa dretvama ti je najjednostavnije, svaka dretva obrađuje jednog klijenta i stvara novi socket. S time postižeš i konkurentnost opisanu u tftpu ( tftp server prima zahtjeve na jedan port, ali odgovara na drugom)


Cvija

A kako si provjeravao je li netascii ili octet u poruci koju prima prilikom RRQ?

Jer meni nekako sve proguta u filename


Cvija

Cvija Napravio sam strukture koje pokrivaju svaki dio
Ovako mi izgleda struktura koja pokriva dio za primanjem zahtjeva:

struct tftp_rrq{
uint16_t code;
uint8_t filename[512];
uint8_t zero;
uint8_t mode[30];
uint8_t zero2;
};


Sashat_Triceps

Cvija Ovako mi izgleda struktura za primanje zahtjeva :
`
struct RRQbuffer{
u_int16_t code;
char fileNameAndMode[100];
};

`
Kasnije u kodu sa strtok-om i u programu izdvojis filename i mode, a strcmp-om usporedis string u modeu s “netascii”, odnosno “octet”


Gussy

Cvija problem ti je što taj rrq paket nema određenu dužinu i koliko sam ja razumio iz specifikacije, ta dva “zero” dijela paketa su zapravo \0.


Cvija

Sasha_Triceps E vidiš, kad tako primim podatak, problem mi je što se u filenameimode spremi samo filename
Mode se ne spremi


Sashat_Triceps

huba buba Ne , mislim da učitavaš po dijelovima u polje. Fileovi su reda veličina nekoliko MB što uzima dosta memorije ako bi ga cijelog išao učitavat. Uzmeš polje od tipa 4KB, učitaš dio podataka u njega i obrađuješ ga. Kad ga obradiš uzmeš novi dio itd itd


Cvija

Cvija [EDIT] riješio
Ako netko ima takav problem, može npr. uzeti strlen od toga i na to mjesto postaviti neki delimiter s kojim će kasnije podijeliti string


Cvija

Treba li program nakon primanja datoteke se zatvoriti ili nastaviti s radom?


Sljedeća stranica »