/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
SOCKET_ERROR
Fra : Jacob Jensen


Dato : 23-08-05 20:24

Jeg kan simpelthen ikke få recv-kaldet i winsock til at returnere
SOCKET_ERROR. Det skulle den ellers ifølge MSDN hvis bufferen indeholder
mere data end recv-kaldet returnerer.

Jacob



 
 
Jacob Jensen (23-08-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-08-05 21:07

> Jeg kan simpelthen ikke få recv-kaldet i winsock til at returnere
> SOCKET_ERROR. Det skulle den ellers ifølge MSDN hvis bufferen indeholder
> mere data end recv-kaldet returnerer.

Efter lidt leg ser det ud til at hvis der er mere i bufferen end recv-kaldet
returnerer så lader den blot resten af det ligge til næste kald. Ingen
fejlmeddelelser eller noget. Gør jeg noget galt? Det virker sådan set godt
nok.

PS: Det er TCP jeg leger med.

Jacob



Michael Rasmussen (23-08-2005)
Kommentar
Fra : Michael Rasmussen


Dato : 23-08-05 21:43

On Tue, 23 Aug 2005 22:06:36 +0200, Jacob Jensen wrote:

>
> Efter lidt leg ser det ud til at hvis der er mere i bufferen end
> recv-kaldet returnerer så lader den blot resten af det ligge til næste
> kald. Ingen fejlmeddelelser eller noget. Gør jeg noget galt? Det virker
> sådan set godt nok.
>
recv ser ud til at fungerer helt i overensstemmelse med beskrivelsen på
msdn (hvilket forøvrigt ved en hurtig gennemlæsning også ser ud til at
fungerer som recv på en Berkley socket).

Fejl bliver generelt kun genereret, hvis der opstår transmissionsfejl,
eller en af parterne afbryder forbindelsen - TCP er
forbindelsesorienteret. Den oplevelse, du har hart, er fuldstændig
korrekt opførsel.

Så lige for at slå det fast: Når din modtagelsesbuffer ikke har mere
plads, vil din socket automatisk fortælle socket i den anden ende, at den
ikke skal sende yderligere, sådan groft forenklet.

--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Jacob Jensen (23-08-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-08-05 22:17

> recv ser ud til at fungerer helt i overensstemmelse med beskrivelsen på
> msdn (hvilket forøvrigt ved en hurtig gennemlæsning også ser ud til at
> fungerer som recv på en Berkley socket).

Ok, jeg læser det lidt forkert så. Jeg læser det som følger: Hvis der er
mere i bufferen end jeg beder om at modtage i recv-kaldet vil det HELE blive
liggende indtil jeg kalder med en stor nok buffer. Desuden genereres en
fejl. Det med fejlen er lidt tvetydigt synes jeg, for de skriver godt nok
"datagram" og det siger man jo normalt kun om UDP, men på den anden side
står det i samme afsnit. Jeg tolker det åbenbart forkert.

Det er jo bare lækkert hvis jeg gør det rigtigt. Lige nu henter jeg (maks)
255 bytes ad gangen og jeg undersøger selv hvornår jeg har fået det data jeg
ønsker. Hvis det hele ikke var med i første omgang henter jeg 255 bytes mere
osv...

> Fejl bliver generelt kun genereret, hvis der opstår transmissionsfejl,
> eller en af parterne afbryder forbindelsen - TCP er
> forbindelsesorienteret. Den oplevelse, du har hart, er fuldstændig
> korrekt opførsel.

ok

> Så lige for at slå det fast: Når din modtagelsesbuffer ikke har mere
> plads, vil din socket automatisk fortælle socket i den anden ende, at den
> ikke skal sende yderligere, sådan groft forenklet.

Ja, det er også hvad jeg har lært :)

Jacob



Michael Rasmussen (23-08-2005)
Kommentar
Fra : Michael Rasmussen


Dato : 23-08-05 23:11

On Tue, 23 Aug 2005 23:16:52 +0200, Jacob Jensen wrote:

>
> Det er jo bare lækkert hvis jeg gør det rigtigt. Lige nu henter jeg (maks)
> 255 bytes ad gangen og jeg undersøger selv hvornår jeg har fået det data jeg
> ønsker. Hvis det hele ikke var med i første omgang henter jeg 255 bytes mere
> osv...
>
Det kan faktisk gøres væsentligt enklere - hvorfor kode til UDP når du
anvender TCP

Du beder om fil x fra serveren. Serveren sender fil x til dig, og du
placerer det modtagne i din buffer, når din buffer er fyldt, stopper du
med at modtage mere, og gør, hvad der nu skal gøres, med data. Herefter
beder du om mere fra serveren, og det hele gentager sig.

while ((bytes = recv(fd, buffer, sizeof(buffer), 0) >= 0))
{
/* Der er data */
if (bytes)
{
behandl data i buffer
}
/* Ikke flere data; transmission afsluttet korrekt */
else
{
Lav eventuel oprydning
Udskriv meddelelse; f.eks antallet af modtagne bytes
afslut
}
}
/* Der var fejl i transmissionen
if (bytes == SOCKET_ERROR)
{
udskriv fejlmeddelelse; Se error codes og deres betydning.
eventuelt exit
}
--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Jacob Jensen (23-08-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-08-05 23:54

> while ((bytes = recv(fd, buffer, sizeof(buffer), 0) >= 0))
> {
> /* Der er data */
> if (bytes)
> {
> behandl data i buffer
> }
> /* Ikke flere data; transmission afsluttet korrekt */
> else
> {
> Lav eventuel oprydning
> Udskriv meddelelse; f.eks antallet af modtagne bytes
> afslut
> }
> }
> /* Der var fejl i transmissionen
> if (bytes == SOCKET_ERROR)
> {
> udskriv fejlmeddelelse; Se error codes og deres betydning.
> eventuelt exit
> }

Kommer du ikke til at stå på en wait nogle gange? Du kan vel komme ud for at
lave en recv hvor bufferen er tom. Det ville jeg gerne undgå, derfor tjekker
jeg lige om jeg skal lav et recv-kald mere. Ellers er det samme
fremgangsmåde.

Jacob



Michael Rasmussen (24-08-2005)
Kommentar
Fra : Michael Rasmussen


Dato : 24-08-05 00:27

On Wed, 24 Aug 2005 00:54:17 +0200, Jacob Jensen wrote:

>
> Kommer du ikke til at stå på en wait nogle gange? Du kan vel komme ud for at
> lave en recv hvor bufferen er tom. Det ville jeg gerne undgå, derfor tjekker
> jeg lige om jeg skal lav et recv-kald mere. Ellers er det samme
> fremgangsmåde.
>
recv står altid på wait, da det er et blokkerende kald.
bufferen vil aldrig være "tom". Den vil som minimum altid indeholde
mindst en tegn ('\0'), når der er sendt fra den anden side.

Hvis du vil finde ud af, om der rent faktisk sendes data til dig, skal du
anvende select. Select kan sættes i non-blocking mode:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp

--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Jacob Jensen (24-08-2005)
Kommentar
Fra : Jacob Jensen


Dato : 24-08-05 09:19

> recv står altid på wait, da det er et blokkerende kald.
> bufferen vil aldrig være "tom". Den vil som minimum altid indeholde
> mindst en tegn ('\0'), når der er sendt fra den anden side.

Hvis der er sendt noget fra den anden side indeholder den vel ikke '\0'?
Hvad når der ikke er sendt noget fra den anden side?
Så vidt jeg kan se kører du i en uendelig løkke fordi den blokkerer når der
ikke er noget i bufferen.

Jeg er ikke helt med :)

> Hvis du vil finde ud af, om der rent faktisk sendes data til dig, skal du
> anvende select. Select kan sættes i non-blocking mode:
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp

ok, det var da en mulighed. Så slipper jeg for noget string.find().

Jacob



Morten Larsen (24-08-2005)
Kommentar
Fra : Morten Larsen


Dato : 24-08-05 13:42

"Jacob Jensen" <omo@adslhome.dk> skrev i en meddelelse
news:430c2d82$0$180$edfadb0f@dtext02.news.tele.dk...
>> recv står altid på wait, da det er et blokkerende kald.
>> bufferen vil aldrig være "tom". Den vil som minimum altid indeholde
>> mindst en tegn ('\0'), når der er sendt fra den anden side.
>
> Hvis der er sendt noget fra den anden side indeholder den vel ikke '\0'?

'\0' bruges til at signallere slutningen af din data. En såkaldt null
terminering.

> Hvad når der ikke er sendt noget fra den anden side?

Så blokere recv, dvs at dit program står stille/ikke forsætter til næste
linie før der er modtaget data.

> Så vidt jeg kan se kører du i en uendelig løkke fordi den blokkerer når
> der ikke er noget i bufferen.

Lykken i Michaels eksempel fortsætter indtil der er en socket-fejl, eller
forbindelsen er lukket.
(recv blokere indtil der er fejl, eller indtil forbindelsen lukkes.)



Morten Larsen (23-08-2005)
Kommentar
Fra : Morten Larsen


Dato : 23-08-05 21:27


"Jacob Jensen" <omo@adslhome.dk> skrev i en meddelelse
news:430b77d5$0$175$edfadb0f@dtext01.news.tele.dk...
> Jeg kan simpelthen ikke få recv-kaldet i winsock til at returnere
> SOCKET_ERROR. Det skulle den ellers ifølge MSDN hvis bufferen indeholder
> mere data end recv-kaldet returnerer.

Det er meget klart beskrevet på msdn.

Og måske skulle du læse det igen.

SOCKET_ERROR returneres hvis der er en fejl. Med WSAGetLastError() kan du få
fejl koden.
WSAEMSGSIZE returneres hvis du bruger udp, og din buffer er mindre end den
data mængde der sendes til dig.
Hvis dette er tilfældet misten du den overskydende data.
Ved tcp gemmens den overskydende data til du kalder recv igen næste gang. Og
den mistes ikke.



Jacob Jensen (23-08-2005)
Kommentar
Fra : Jacob Jensen


Dato : 23-08-05 22:23

> Og måske skulle du læse det igen.

Jeg har prøvet mange gange, men jeg er også lidt ny til
netværksprogrammering. Som jeg svarede michael så tolker jeg sætningen lidt
forkert åbenbart.

> SOCKET_ERROR returneres hvis der er en fejl. Med WSAGetLastError() kan du
> få fejl koden.
> WSAEMSGSIZE returneres hvis du bruger udp, og din buffer er mindre end den
> data mængde der sendes til dig.
> Hvis dette er tilfældet misten du den overskydende data.
> Ved tcp gemmens den overskydende data til du kalder recv igen næste gang.
> Og den mistes ikke.

Tak, det er vist også sådan jeg kom frem til at det måtte virke.

Jeg synes det er svært at overskue alle de fejl og hvornår og hvor man skal
tage højde for dem.

Jacob



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste