Avatar billede jakobdo Ekspert
18. maj 2003 - 21:53 Der er 23 kommentarer og
1 løsning

Klient, som connecter til socket.

Hej igen... :o)

Jeg har en kode, som skal connecte til en pop3 server...
For at den hele tiden kan bearbejde det data den får, har jeg lavet koden som følger:

for(;;)
{
  if(recv(socket,buffer,BUFFERSIZE,0))
  {
    //Hvad der nu skal gøres...
  }
}

Kan jeg ikke også lave det på denne måde:

while(recv(socket,buffer,BUFFERSIZE,0)
{
  //Hvad der nu skal gøres...
}

Gør disse ikke mere eller mindre det samme...
Ifølge mit lille hoved burde de, men synes dog min kode giver et andet resultat! :o)
Måske jeg overser noget vigtigt...
Avatar billede arne_v Ekspert
18. maj 2003 - 22:21 #1
Nej - den første læser kun en gang.

Den anden læser flere gange.

Det er normalt med konstruktioner a la:

int ix = 0;
while((n = recv(s,buf+ix,sizeof(buf)-ix,0)>=0) {
    ix+=n;
}
Avatar billede jakobdo Ekspert
18. maj 2003 - 22:25 #2
Hvad gør denne konstruktion lige helt præcist??
Jeg forstår den nemlig ikke 100%...
Avatar billede arne_v Ekspert
18. maj 2003 - 22:31 #3
Lad os sige at vi skal have læst 30 bytes og at de tilfældigvis kommer
i 3 klumper af 11, 9 og 10 bytes.

ix = 0

første gennemløb

vi læser ind i buf+0
antal bytes læst denne gang n = 11
antal bytes læst ialt ix = 0 + 11

andet gennemløb

vi læser ind i buf+11
antal bytes læst denne gang n = 9
antal bytes læst ialt ix = 11 + 9

tredie gennemløb

vi læser ind i buf+20
antal bytes læst denne gang n = 10
antal bytes læst ialt ix = 20 + 10

fjerde gennemløb

n = -1 så vi hopper ud

nu har vi fået læst de 30 bytes ind i buf og ix=30 fortæller os hvor
mange bytes vi har læst.
Avatar billede jakobdo Ekspert
18. maj 2003 - 22:39 #4
Jeg skal jo så yderligere parse det jeg modtager...
Så vil det evt være en ide at læse et tegn ad gangen??

Og hvad er det smarte i det du beskrev ovenover??
Avatar billede jakobdo Ekspert
18. maj 2003 - 22:45 #5
Din kode giver et mærkeligt resultat!

int n,ix = 0;
char *buf;
mailSocket = den socket som er connected til server...
while(n = recv(mailSocket, buf+ix, sizeof(buf)-ix, 0) >= 0)
{
  ix+=n;
}
printf("%s - %d\n",buf,ix);
return 0;

Koden køres, og giver følgende svar: UåWVSì - 0
Burde vel være: +OK Hello there.
Avatar billede arne_v Ekspert
18. maj 2003 - 22:46 #6
Man kan jo så altid parse buf.

[husk at lave en buf[ix]='\0'; hvis det skal være en C streng]

Det smarte er at man får læst alle data.

Hvis man kun lavede en read uden løkke, så ville man jo kun
have 11 tegn i bug og mangle 19 tegn.

Hvis man har en løkke men processer det man har løst inden i løkken så
får man problemer hvis knækket sker midt i noget.
Avatar billede arne_v Ekspert
18. maj 2003 - 22:48 #7
Prøv lige med:

1)

char buf[1000];

2)

buf[ix]='\0'
Avatar billede arne_v Ekspert
18. maj 2003 - 22:49 #8
#2 skal være efter løkken.
Avatar billede jakobdo Ekspert
18. maj 2003 - 22:53 #9
char buf[1000];
while(n = recv(mailSocket, buf+ix, sizeof(buf)-ix, 0) >= 0)
{
  ix+=n;
  printf("ix = %d, n = %d\n",ix,n);
}
buf[ix]='\0';
printf("%s - %d\n",buf,ix);

Giver dette output:
ix = 1, n = 1

Og så looper den uden at lave noget....
Avatar billede jakobdo Ekspert
18. maj 2003 - 22:56 #10
Dette:

while(n = recv(mailSocket, buf+ix, sizeof(buf)-ix, 0) >= 0)
    {
        printf("ix = %d, n = %d, buf = %s\n",ix,n,buf);
        ix+=n;
        printf("ix = %d, n = %d\n",ix,n);
    }
    buf[ix]='\0';
    printf("%s - %d\n",buf,ix);

Giver følgende svar:

ix = 0, n = 1, buf = +OK Hello there.
@
õÿ¿\Â
ix = 1, n = 1

N, viser en, men den har jo læst +OK Hello there. (lidt mere end 1)
Avatar billede arne_v Ekspert
18. maj 2003 - 22:58 #11
Mystisk. Det burde virke.

Og den kan da ihvertfald ikke loope med ix=1 n=1 fordi ix bliver talt op med n !?

Prøv evt. med >0 i stedetfor >=0 !
Avatar billede arne_v Ekspert
18. maj 2003 - 23:00 #12
Meget mystisk.

recv bør returnere antal bytes læst !??
Avatar billede jakobdo Ekspert
18. maj 2003 - 23:00 #13
Jeg har lidt erfaringer, det crap som du ser efter there. og før ix = 1, skyldes at bufferen indeholder crap data, med en memset(buf,'\0',sizeof(buf)) bliver outputtet pænere....

At koden kommer til at hænge, skyldes jo at den vil have en kode! Ala USER XXXX....
Avatar billede jakobdo Ekspert
18. maj 2003 - 23:03 #14
Der er something wrong in the world today...
Koden:

memset(buf,'\0',sizeof(buf));
    while(n = recv(mailSocket, buf+ix, sizeof(buf)-ix, 0) > 0)
    {
        printf("ix = %d, n = %d, buf = %s\n",ix,n,buf);
        ix+=n;
        printf("ix = %d, n = %d\n",ix,n);
    }

Giver output:
ix = 0, n = 1, buf = +OK Hello there.

ix = 1, n = 1

N skulle da ikke indeholde 1, men 18 eller sådan noget!
(længden af: +OK Hello there.\r\n)
Avatar billede arne_v Ekspert
18. maj 2003 - 23:06 #15
Nu er jeg lidt bange for at jeg er lost.

Selve konstruktionen burde være OK.

Hvis du har en single request + single response protokol, så er det OK.

Hvis du har en request+response+request+respon+.... protokol så
er du nødt til at ligge yderligere en betingelse ind i while løkken:

char buf[1000];
int ix = 0;
int done = 0;
while((n = recv(mailSocket, buf+ix, sizeof(buf)-ix, 0) > 0) && !done)
{
  ix+=n;
  if(buf set færdig ud) done=1;
}
buf[ix]='\0';
Avatar billede arne_v Ekspert
18. maj 2003 - 23:08 #16
Ja.

recv skal returnere læst antal tegn.
Avatar billede arne_v Ekspert
18. maj 2003 - 23:11 #17
Er buf erklæret korrekt ?

Og er ix initialiseret med 0 ?
Avatar billede jakobdo Ekspert
18. maj 2003 - 23:21 #18
char buf[1000];
int n,ix = 0;
int done = 0;
memset(buf,'\0',sizeof(buf));
while((n = read(mailSocket, buf+ix, sizeof(buf)-ix) > 0) && !done)
{
    printf("n = %d,buf = %s\n",n,buf);
    ix+=n;
    if(strncmp(buf,"+OK",3))
        done=1;
}
buf[ix]='\0';
printf("%s - %d\n",buf,ix);

prøvede at ændre recv med read...
samme resultat:
n = 1,buf = +OK Hello there.

Jeg giver op for i dag, må nok hellere få sovet lidt...
Men det virker sgu lidt mærkeligt...

Bruger jeg funktionen forkert??
Avatar billede arne_v Ekspert
18. maj 2003 - 23:27 #19
Der ser meget rigtigt ud.

Så jeg forstå det ikke.

Har du inkluderet de rigtige header-filer ?
Avatar billede arne_v Ekspert
18. maj 2003 - 23:36 #20
Jeg har lige testet.

Dette her virker hos mig:

  ix=0;
  while ((len=recv(sd,resp+ix,sizeof(resp)-ix-1,0))>0) {
      ix = ix + len;
  }
  resp[ix]='\0';
  printf("%s",resp);
Avatar billede jakobdo Ekspert
19. maj 2003 - 07:47 #21
Jeg har disse headere:

#include <stdio.h>    //Standard C library for Input/Output with streams
#include <unistd.h>    //standard symbolic constants and types
#include <sys/types.h>  //data types
#include <netdb.h>    //definitions for network database operations
#include <sys/socket.h> //Internet Protocol family
#include <netinet/in.h> //Internet Protocol family
#include <string.h>    //string operations
Avatar billede jakobdo Ekspert
19. maj 2003 - 08:25 #22
Hej Arne, nu har jeg også fået det til at virke...
Ved dog ikke hvad der var galt... Men startede helt fra bunden med ny kode. :o)
Avatar billede arne_v Ekspert
19. maj 2003 - 08:27 #23
Med while løkken ?
Avatar billede jakobdo Ekspert
19. maj 2003 - 17:02 #24
Ja, (WHILE-løkken) det virker lidt spøjs...
Den returnere fint 18, som antal bytes læst..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester