| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | 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 |  
  |   |   |   
            
        
 
            
         
                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 
 
 
  
            
             |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |