Avatar billede cybermike Nybegynder
17. august 2003 - 21:09 Der er 3 kommentarer og
1 løsning

Nonblocking sockets

Skal bruge flg. eksempel skrevet med nonblocking sockets(el. evt anden metode der loeser samme problem)

Aabner en socket til en given host paa en given port, det er paa forhaand givet at denne port er aaben, derefter skal denne vente 5 sekunder og se om der bliver sendt data og i saa fald skal disse gemmes (saakaldt bannergrab) sker der ikke noget inden disse 5 sekunder skal forbindelsen lukkes og programmets udfoersel fortsaette.

Alle eksempler jeg har funder med nonblocking sockets er til server siden.


  mike

ps. platformen er unix
Avatar billede arne_v Ekspert
17. august 2003 - 22:24 #1
Det her er sikkert ikke jordens bedste eksempel.

Men det illusterer den rimeligt lille fordel mellem blocking og non-blocking
client.

Eksemplet henter en side via HTTP.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>

void get(char *hostname,int port,char *path,int noblock)
{
  int sd,status,len,ix,tmp;
  char cmd[512],resp[51200];
  struct sockaddr local,remote;
  struct hostent *hostinfo;
  time_t t;
  /* create socket */
  sd=socket(AF_INET,SOCK_STREAM,0);
  if(sd<0) {
      printf("Error creating socket: %s\n",strerror(errno));
      goto fin;
  }
  /* bind socket */
  local.sa_family=AF_INET;
  memset(local.sa_data,0,sizeof(local.sa_data));
  status=bind(sd,&local,sizeof(local));
  if(status<0) {
      printf("Error binding socket: %s\n",strerror(errno));
      goto fin;
  }
  /* lookup host */
  hostinfo=gethostbyname(hostname);
  if(!hostinfo) {
      printf("Error looking up host: %s\n",hostname);
      goto fin;
  }
  /* connect to host */
  remote.sa_family=hostinfo->h_addrtype;
  memcpy(remote.sa_data+2,hostinfo->h_addr_list[0],hostinfo->h_length);
  *((short *)remote.sa_data)=port;
  tmp=remote.sa_data[0];
  remote.sa_data[0]=remote.sa_data[1];
  remote.sa_data[1]=tmp;
  status=connect(sd,&remote,sizeof(remote));
  if(status!=0) {
      printf("Error connecting to host: %s port: %d\n",hostname,port);
      goto fin;
  }
  /* send GET request */
  sprintf(cmd,"GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",path,hostname);
  status=send(sd,cmd,strlen(cmd),0);
  if(status<0) {
      printf("Error sending POST request\n");
      goto fin;
  }
  /* read response */
  ix=0;
  if(noblock) {
      status=fcntl(sd,F_SETFL,O_NONBLOCK);
      if(status<0) {
        printf("Error setting socket nonblocked: %s\n",strerror(errno));
        goto fin;
      }
      t=time(NULL);
      while (time(NULL)<(t+5)) {
        len=recv(sd,resp+ix,sizeof(resp)-ix-1,0);
        ix = ix + len;
        printf("no blocking read %d bytes\n",len);
        sleep(1);
      }
  } else {
      while ((len=recv(sd,resp+ix,sizeof(resp)-ix-1,0))>0) {
        ix = ix + len;
        printf("blocking read %d bytes\n",len);
      }
  }
  resp[ix]='\0';
  /*printf("%s",resp);*/
fin:
  close(sd);
  return;
}

int main(int argc,char *argv[])
{
  get("www.xxx.dk",80,"/",0);
  get("www.xxx.dk",80,"/",1);
}

Output på minLinux box:

blocking read 241 bytes
blocking read 1460 bytes
blocking read 72 bytes
no blocking read -1 bytes
no blocking read 1773 bytes
no blocking read 0 bytes
no blocking read 0 bytes
Avatar billede arne_v Ekspert
10. september 2003 - 22:14 #2
OK ?
Avatar billede cybermike Nybegynder
26. oktober 2003 - 21:53 #3
lukkes
Avatar billede arne_v Ekspert
26. oktober 2003 - 22:16 #4
Hvad var der galt med det eksempel ?
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