Gå til innhold

Ukjent størelse på buffer, recv()


Anbefalte innlegg

Hei!

Jeg har begynt så smått med sockets, men det er noe jeg sliter litt med.

Når jeg bruker funksjonen recv() for å motta noe som blir sendt så må jeg angi størelsen i bytes på det jeg mottar, eller sette en maks på noe jeg skal motta, men hva hvis jeg ikke vil ha noen maks grense men vil ha muligheten til å motta alt av tekst etc, som blir sendt? Hva skal jeg sette der da?

 

Håper dere forstår hva problemet mitt er og kan hjelpe meg.. :)

 

På forhånd takk!

Lenke til kommentar
Videoannonse
Annonse

Vel det kommer helt an på hvilke protokoll du bruker, bruker du TCP/IP så er det bare å kalle recv() så mange ganger og så fort du kan, det finnes ingen garantert metode som sikrer at du får alt du må bare lage bufferen så stor som mulig, men det er ikke bare bare det heller.

 

Bruker du f. eks. UDP så må du sørge for å ha større buffer enn størrelsen på pakken som blir sendt, eventuelt maks datagram størrelse for protokollen.

 

Så i korte ord så kan du ikke ha en uendelig stor buffer. Du må kalle på recv() flere ganger hvis du ikke får med deg alt.

 

nettverk er ikke min sterkeste side, men jeg tror det meste stemmer.

 

hvis du beskrev problemet ditt litt mer så hadde det muligens vært enklere å gi spesifikk hjelp

Lenke til kommentar

Hei! Takk for svar!

Jeg benytter meg av TCP. Alltså må jeg kjøre en while løkke med recv() helt til jeg møter enden på det som sender? Hvordan vet jeg når jeg har møtt enden isåfall?

Og hvordan funker det, vil bufferen inneholde all data når den løkken er ferdig, eller må jeg ta dataen i bufferen og legge til i en annen variabel etter recv()?

 

Også har jeg et lite spørsmål til, hva må jeg bruke for at input fra brukeren skal kunne lagres i hel tekst i en char? Hvis jeg feks. bruker cin >> char så kommer kun det første ordet..

Endret av 0lav
Lenke til kommentar
Også har jeg et lite spørsmål til, hva må jeg bruke for at input fra brukeren skal kunne lagres i hel tekst i en char? Hvis jeg feks. bruker cin >> char så kommer kun det første ordet..

8621136[/snapback]

 

Du kan bruke en char peker.

Denne kan ta 100 tegn.

char * streng = new char[100];

Lenke til kommentar

Takk for svar!

 

Også har jeg et lite spørsmål til, hva må jeg bruke for at input fra brukeren skal kunne lagres i hel tekst i en char? Hvis jeg feks. bruker cin >> char så kommer kun det første ordet..

8621136[/snapback]

 

Du kan bruke en char peker.

Denne kan ta 100 tegn.

char * streng = new char[100];

8621741[/snapback]

 

Det er en char peker jeg bruker, men problemet kommer når jeg skal lese inn fra det brukeren skriver i vinduet og inn til char'en.

Hvis jeg feks bruker denne koden:

cin >> streng;

Og brukeren feks. skriver "Hei på deg!" så blir kun "Hei" lagret i strengen. Så jeg ser etter noe lignende som getline() bare at det kan brukes på char... :)

 

 

EDIT: staalezh: Takk for svar til deg også! Men getline() kan vell ikke brukes på char? Eller tar jeg helt feil der? For hvis jeg skal sende det som blir skrevet med send() så må jeg ha det i en char, right?

Endret av 0lav
Lenke til kommentar
Takk for svar!

 

Også har jeg et lite spørsmål til, hva må jeg bruke for at input fra brukeren skal kunne lagres i hel tekst i en char? Hvis jeg feks. bruker cin >> char så kommer kun det første ordet..

8621136[/snapback]

 

Du kan bruke en char peker.

Denne kan ta 100 tegn.

char * streng = new char[100];

8621741[/snapback]

 

Det er en char peker jeg bruker, men problemet kommer når jeg skal lese inn fra det brukeren skriver i vinduet og inn til char'en.

Hvis jeg feks bruker denne koden:

cin >> streng;

Og brukeren feks. skriver "Hei på deg!" så blir kun "Hei" lagret i strengen. Så jeg ser etter noe lignende som getline() bare at det kan brukes på char... :)

 

 

EDIT: staalezh: Takk for svar til deg også! Men getline() kan vell ikke brukes på char? Eller tar jeg helt feil der? For hvis jeg skal sende det som blir skrevet med send() så må jeg ha det i en char, right?

8621863[/snapback]

 

bruk denne :

cin.get(streng, 100);

som vil lese inn maks 100 tegn i pekeren.. streng som må være den størrelsen.

Lenke til kommentar
Jeg benytter meg av TCP. Alltså må jeg kjøre en while løkke med recv() helt til jeg møter enden på det som sender? Hvordan vet jeg når jeg har møtt enden isåfall?

8621136[/snapback]

 

Vel du vet aldri når du har møtt enden. Du må selv definere en start og slutt.

fks et veldig veldig enkel chatte program.

 

STARTåssen går det med deg daSLUTT

 

så når du leser START så vet du at en den linje kommer og når du leser SLUTT så vet du at du har motatt hele linjen og du kan da vise linjen til brukeren

 

Et mer realistisk og bedre pakke hode er vel noe ala dette.

 

struct BasicPacketHeader
{
unsigned int PacketID;
unsigned int PacketSize;	
}

 

Da vet du åssen pakke det er og hvor stor pakke er og vet da hvor lange den er og hvor den slutter.

 

Og hvordan funker det, vil bufferen inneholde all data når den løkken er ferdig, eller må jeg ta dataen i bufferen og legge til i en annen variabel etter recv()?

8621136[/snapback]

 

Vel løkken vil/burde aldri slutte, løkken skal og burde gå hele tiden mens socketen er oppe. Du må ikke finne på å bruke samme buffer med samme peker hele tiden, da vil recv() bare skrive over det du tidligere har motatt, men du kan flytte buffer pekeren det samme antall byte som det du har motatt og da vil du kunne bruke samme bufferen helt til den fylt opp.

Lenke til kommentar

Takk for svar! Tror jeg har skjønt det litt bedre nå, men når jeg kjører den while løkken, hvor skal jeg printe ut bufferen hvis jeg vil vise det som blir mottat til brukeren? I løkken? Og hvordan flytter jeg buffer pekeren? Det vil da si at den skriver til bufferen etter det andre som ligger i bufferen fra før?

Lenke til kommentar
Takk for svar! Tror jeg har skjønt det litt bedre nå, men når jeg kjører den while løkken, hvor skal jeg printe ut bufferen hvis jeg vil vise det som blir mottat til brukeren? I løkken? Og hvordan flytter jeg buffer pekeren? Det vil da si at den skriver til bufferen etter det andre som ligger i bufferen fra før?

8630431[/snapback]

 

vel du kan godt legge inn recv() i program løkken din, men du må bare ikke stoppe å skjekke med recv(),

 

når det gjelder flytting av bufferpointer

 

init:

char* bufferstart = new char[1000];

CurBufferPoint = bufferstart;

 

så for vær recv() gjør dette, skjekk også at du ikke vandrer utenfor bufferstørelsen og at du angir den gjenværende størelse til recv()

CurBufferPoint =bufferstart + motatebyte;

 

jaja nå må jeg ut å gå i tog..

 

God 17. mai folkens...

Lenke til kommentar
vel du kan godt legge inn recv() i program løkken din, men du må bare ikke stoppe å skjekke med recv(),

Hvis du har satt socketen til å være non-blocking kan du godt kalle recv() periodisk. Hvis ingen melding er tilgjengelig vil den returnere -1. Hvis en melding er tilgjengelig kan du kalle recv() flere ganger umiddelbart etterhverandre inntil den returnerer -1. Da vet du at bufferet er tomt. Se http://www.penguin-soft.com/penguin/man/2/...man2/recv.2.inc

 

Har ikke drevet så mye med socket-programmering, men tror det er slik.

/Martin

Lenke til kommentar

Takk for svar fra alle.. Har fått til det meste jeg lurte på nå :)..

 

 

EDIT: Hvordan kan jeg linke inn lib filer til et prosjekt i Visual C++ 2005 express edition? Finner ikke ut hvor jeg gjør dette, i Dev-C++ var det jo bare å legge de til på project properties.. :S

Endret av 0lav
Lenke til kommentar
Takk for svar fra alle.. Har fått til det meste jeg lurte på nå :)..

 

EDIT: Hvordan kan jeg linke inn lib filer til et prosjekt i Visual C++ 2005 express edition? Finner ikke ut hvor jeg gjør dette, i Dev-C++ var det jo bare å legge de til på project properties.. :S

8653837[/snapback]

 

Configuration Properties->Linker->Input->Additional Dependencies

 

Ellers så kan du bruke #pragma

#pragma comment(lib, "OpenAL32.lib")

Lenke til kommentar

Takk for svar! Men hvis jeg vil bruke Additional Dependencies isteden for #pragma. Hvordan gjør jeg det? Når jeg trykker på den knappen for å legge til ting så kommer det opp et nytt vindu med noen macros etc. Men jeg finner ingen knapp jeg kan trykke på for å bla meg fram til et lib?

Lenke til kommentar
Du kan jo bruke vector, den er jo garantert sekvensiell.

std::vector<char> v;

 

recv(v[0], ... );

 

 

(veldig lenge siden jeg har drevet med dette, så syntaks kan være litt feil)

8676509[/snapback]

 

Hvorfor skal det være bedre å bruke vector?

Vector er jo strengt tatt en array som man resizer... aka. lager en helt ny buffer og kopierer innholdet dit

Lenke til kommentar

Ikke som "man" resizer, STL gjør dette for deg.

 

Vector fordi det er enkelt, og fordi det har plass til "alt".

Hvorfor rote med dynamisk allokering og pekere når man kan la STL gjøre dette for seg? Det er nok bare smak og behag, men da jeg oppdaget at man kunne bruke en vector istedenfor et fixed size char array, ble jeg glad. Ville bare dele det videre :)

Lenke til kommentar
Ikke som "man" resizer, STL gjør dette for deg.

 

Vector fordi det er enkelt, og fordi det har plass til "alt".

Hvorfor rote med dynamisk allokering og pekere når man kan la STL gjøre dette for seg? Det er nok bare smak og behag, men da jeg oppdaget at man kunne bruke en vector istedenfor et fixed size char array, ble jeg glad. Ville bare dele det videre :)

8678304[/snapback]

 

hmm.. hvis du ikke bruker resize bruker du da en vanlig array til selve recv() og så bruker insert i vectoren eller finnes det andre fiffie metoder?

 

Du har helt rett i at det er smak og behag og det er nok litt enklere, men det er viktig og ikke glemme det som ligger bak.

Tenk på hvordan størrelsen på vektoren vil bli etter lang bruk med en god del dataoverføring :)

Du har absolutt et poeng, jeg har bare aldri tenkt i de baner :D

Lenke til kommentar

vectoren øker i størrelse automagisk. Ikke spør meg hvordan eller hvorfor (har ikke sjekket), men jeg mener det var kjetil7 som skrev koden som brukte dette første gang. Mulig du kan søke deg frem til det på forumet.

 

Slik jeg husker det så opprettet du vectoren, og anga &v[0] til recv (se eks. over), så kunne du lese ut hele pakken med iteratorer etterpå.

Lenke til kommentar
vectoren øker i størrelse automagisk. Ikke spør meg hvordan eller hvorfor (har ikke sjekket), men jeg mener det var kjetil7 som skrev koden som brukte dette første gang. Mulig du kan søke deg frem til det på forumet.

 

Slik jeg husker det så opprettet du vectoren, og anga &v[0] til recv (se eks. over), så kunne du lese ut hele pakken med iteratorer etterpå.

8682754[/snapback]

 

automagisk :D

 

Har du testet dette?

Jeg ville tro at dette ga en lese/skrive feil jeg (hvis vectorens størrelse ikke er stor nok)

Mulig jeg ikke kjenner std::vector så godt som jeg trodde :(

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...