Toon posts:

[Linux C] Raar gedrag select?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als ik sockets controleer mbv select, werkt dat prima als er geen timeout wordt gespecificeerd. Iedere keer als de verbinding verbroken wordt, wordt dit gemeld als readable en als er een verbinding succesvol gemaakt is, wordt dit gemeld als writeable.

Als ik echter een time-out instel (bv 5 seconden), gaat dit goed zolang de events optreden binnen de time-out periode. Als select een of meer keer een time-out heeft aangegeven (return value 0), wordt er niets meer gerapporteerd en krijg ik alleen nog maar time-outs.

De code hieronder verhuist file-descriptors van de readable set naar de writeable set en omgekeerd afhankelijk van de status van de verbinding.

Ik gebruik RH7.2 zonder patches en updates; in bugzilla kon ik niets vinden. Iemand advies of een idee wat fout gaat?

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
int start_comms(sCFG *pCfg)
{
fd_set rfds,wfds,efds;
int rc,cnt,rc2;
char dummy[16];
int socktype;

struct timeval tv;

  // check supported protocol
  switch(pCfg->mydevice.proto)
  {
  case PROTO_TCP:
    socktype=SOCK_STREAM;
    break;
  default:
    errorlog(pCfg->eflags,0,"init_comms",
             "Invalid or unsupported protocol for communication with devices");
    return 1;
  }

  // initialize sets
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  // initial connect
  if(pCfg->mydevice.type==TYPE_CLNT)
  {
    for(cnt=0;cnt<pCfg->device_cnt;cnt++)
    {
      if(iolan_connect(pCfg->pDevice[cnt].fd,&pCfg->pDevice[cnt].addr))
        // success, so add to readable set
        FD_SET(pCfg->pDevice[cnt].fd,&rfds);
      else
        // error, so add to writeable set
        FD_SET(pCfg->pDevice[cnt].fd,&wfds);
    }
  }
  else
  {
    // listen
    // accept
  }

  while(1)
  {
    tv.tv_sec=5;
    tv.tv_usec=0;
    rc=select(pCfg->pDevice[pCfg->device_cnt-1].fd+1,&rfds,&wfds,NULL,&tv);
//    rc=select(pCfg->pDevice[pCfg->device_cnt-1].fd+1,&rfds,&wfds,NULL,NULL);
    printf("select returned: %d\n",rc);

//    if(rc!=0)
    {
      for(cnt=0;cnt<pCfg->device_cnt;cnt++)
      {
        if(FD_ISSET(pCfg->pDevice[cnt].fd,&rfds))
        {
          // there's something to read
          printf("\nsomething to read on %d\n",pCfg->pDevice[cnt].fd);
          rc2=read(pCfg->pDevice[cnt].fd,dummy,sizeof(dummy));
          if(rc2<0)
          {
            errorlog(pCfg->eflags,errno,"start_comms","");
//            FD_CLR( pCfg->pDevice[cnt].fd,&rfds); // remove from read
            if(iolan_connect(pCfg->pDevice[cnt].fd,&pCfg->pDevice[cnt].addr))
            {
              printf("%d: from rd to wr\n",pCfg->pDevice[cnt].fd);
              FD_CLR( pCfg->pDevice[cnt].fd,&rfds); // remove from read
              FD_SET( pCfg->pDevice[cnt].fd,&wfds); // add to write
            }
            else
            {
              errorlog(pCfg->eflags,errno,"start_comms","");
            }
          }
          if(rc2==0)
          {
            printf("EOF detected\n");
        close(pCfg->pDevice[cnt].fd);       // close and reconnect
            pCfg->pDevice[cnt].fd=socket(PF_INET,socktype,0);
            printf("socket: %d\n",pCfg->pDevice[cnt].fd);
          }
          if(rc2>0)
          {
            printf("There's data\n");
          }
        }

        if(FD_ISSET(pCfg->pDevice[cnt].fd,&wfds))
        {
          // we can write something
          printf("\ncan write on %d\n",pCfg->pDevice[cnt].fd);
          printf("%d: from wr to rd\n",pCfg->pDevice[cnt].fd);
          FD_CLR( pCfg->pDevice[cnt].fd,&wfds);     // remove from write
          FD_SET( pCfg->pDevice[cnt].fd,&rfds);     // add to read
        }
      } // end_of_for
    }
  }

  printf("end\n");

  return 0;
}


PS: alle sockets zijn gecreeerd als de bovenstaande functie wordt aangeroepen.

[ Voor 14% gewijzigd door .oisyn op 20-03-2003 10:08 ]


Verwijderd

Topicstarter
Probleem is opgelost door de sets opnieuw aan te maken aan het begin van de loop |:( Kan iemand uitleggen waarom dat nodig is na een time-out :? De sets zijn dan niet veranderd en volgens mij nog steeds geldig.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

volgens mij wel: de sets worden geleegd omdat er geen enkele socket gereed is om van te lezen of te schrijven

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Thijsch
  • Registratie: Februari 2002
  • Laatst online: 22-08 19:17
in regel 54/55 zit ook iets raars, de if is out-commented maar de { staat er nog wel

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:27

Creepy

Tactical Espionage Splatterer

ParaDot schreef op 20 maart 2003 @ 15:24:
in regel 54/55 zit ook iets raars, de if is out-commented maar de { staat er nog wel
Aangezien de bijbehorende } er ook nog staat is het niet echt een probleem ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Dat was de snelste manier om even iets te testen :D
Iedereen bedankt, een nieuwe post is in de maak over dit onderwerp :'(
Pagina: 1