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?
PS: alle sockets zijn gecreeerd als de bovenstaande functie wordt aangeroepen.
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 ]