Ik heb een (zelf-geschreven) programma dat moet starten als de PC gestart wordt.
Dit programma is een client en verbindt met een (externe) server over een TCP/IP verbinding. Het programma doet drie pogingen met een interval van 1 seconde.
Als ik dit programma handmatig start, gaat dit 100% van de keren goed en de verbinding wordt direct gemaakt (1ste poging). Het maakt niet uit of het programma via een script gestart wordt of van de commandline. Het maakt ook niet uit of ik het draai als root of als een gebruiker.
Als ik dit programma vanuit rc.local start krijg ik in ongeveer 20% van de gevallen een foutmelding dat de verbinding niet gemaakt kan worden, ook niet na 3 pogingen.
Een ping (met raw sockets) naar het betreffende adres (vanuit het programma) gaat wel goed hetgeen aangeeft dat de externe server wel aan staat.
De externe server is een stuk hardware waar verder winig invloed op kan worden uitgeoefend en die niet uitgeschakeld is tijdens de diverse reboots van de PC waar het programma op draait.
Oh ja, het programma wordt altijd gestart als een achtergrond process en wordt gestopt via kill. Er is een signal-handler die alle sockets sluit voordat het programma stopt.
Iemand enig idee waarom het niet betrouwbaar werkt via rc.local?
Deze code wordt aangeroepen totdat pConn->inuse gezet is. CONNECTIONTO is 1 en MAXCONNATTEMPTS is 3.
Dit programma is een client en verbindt met een (externe) server over een TCP/IP verbinding. Het programma doet drie pogingen met een interval van 1 seconde.
Als ik dit programma handmatig start, gaat dit 100% van de keren goed en de verbinding wordt direct gemaakt (1ste poging). Het maakt niet uit of het programma via een script gestart wordt of van de commandline. Het maakt ook niet uit of ik het draai als root of als een gebruiker.
Als ik dit programma vanuit rc.local start krijg ik in ongeveer 20% van de gevallen een foutmelding dat de verbinding niet gemaakt kan worden, ook niet na 3 pogingen.
Een ping (met raw sockets) naar het betreffende adres (vanuit het programma) gaat wel goed hetgeen aangeeft dat de externe server wel aan staat.
De externe server is een stuk hardware waar verder winig invloed op kan worden uitgeoefend en die niet uitgeschakeld is tijdens de diverse reboots van de PC waar het programma op draait.
Oh ja, het programma wordt altijd gestart als een achtergrond process en wordt gestopt via kill. Er is een signal-handler die alle sockets sluit voordat het programma stopt.
Iemand enig idee waarom het niet betrouwbaar werkt via rc.local?
edit:
een foutje gevonden; zou geen invloed moeten hebben aangezien ik (als het fout gaat) nooit een melding krijg dat het eerst succesvol was (connected (1))
zie bugfix
een foutje gevonden; zou geen invloed moeten hebben aangezien ik (als het fout gaat) nooit een melding krijg dat het eerst succesvol was (connected (1))
zie bugfix
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
| static int device_connect(sCONN *pConn, int socktype, sCFG *pCfg) { int rc; // create socket if current socket invalid (-1) if(pConn->connfd<0) { logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0, "device_connect",NULL,0, "creating socket; initial value ='%d'",pConn->connfd); // create socket pConn->connfd=socket(PF_INET,socktype,0); if(pConn->connfd<0) { // error logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,errno, "device_connect",NULL,0, "Socket error"); // TO DO: inform IOCM here return 0; } // end_of_if(pConn->connfd<0) // make socket non-blocking rc=fcntl(pConn->connfd,F_SETFL, fcntl(pConn->connfd,F_GETFL)|O_NONBLOCK); if(rc<0) { logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,errno, "device_connect",NULL,0, "fcntl failed"); } pConn->inuse=0; // initialize counter pConn->attempts=MAXCONNATTEMPTS; pConn->endtime=time(NULL)+CONNECTIONTO; } // end_of_if(pConn->connfd<0) // try to connect when we have a valid socket if(pConn->connfd>=0) // socket created { if(pConn->inuse==0) { logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0, "device_connect",NULL,0, "trying to connect socket '%d'",pConn->connfd); // not in use, attempt to connect if(connect(pConn->connfd,(struct sockaddr*)&pConn->addr, sizeof(pConn->addr))!=0) { // connection 'error' if(errno==EISCONN) // EISCONN equals errno 106 { // if already connected, we're connected logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0, "device_connect",NULL,0, "Device '%s' ('%s:%d') connected (1)", pConn->device, inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port)); proc_iolan(pCfg,pConn->addr,1); pConn->inuse=1; // bugfix return 0; } if(time(NULL)-pConn->endtime>0) { pConn->endtime=time(NULL)+CONNECTIONTO; pConn->attempts--; if(pConn->attempts==0) { // MAXCONNATTEMPTS reached, inform IOCM logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0, "device_connect",NULL,0, "Device '%s' ('%s:%d') disconnected (3)", pConn->device, inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port)); proc_iolan(pCfg,pConn->addr,0); close(pConn->connfd); pConn->connfd=-1; pConn->inuse=0; pConn->attempts=MAXCONNATTEMPTS; } } } // end_of_if(connect(....)!=0) else { logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0, "device_connect",NULL,0, "Device '%s' ('%s:%d') connected (2)", pConn->device, inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port)); proc_iolan(pCfg,pConn->addr,1); pConn->inuse=1; } // end_of_else(connect(....)!=0) } } // end_of_if(pConn->fd>=0) return 0; } |
Deze code wordt aangeroepen totdat pConn->inuse gezet is. CONNECTIONTO is 1 en MAXCONNATTEMPTS is 3.
[ Voor 16% gewijzigd door Verwijderd op 24-07-2003 09:31 ]