Bonjour à tous,

Voici mon problème:
J'ai une application redondante sous XP avec 3 threads, 2 sont utilisé pour savoir si l'ordinateur partenaire est actif, le troisième est le thread principal de l'application.

Le thread principal doit de temps en temps copier ses fichiers à jours sur le partenaire (via un partage netbios), si celui-ci est dispo.

Pour celà un des thread va tenter de temps en temps de voir si le port netbios 139 est ouvert sur le partenaire en faisant un connect sur ce port.

Le problème est que si le partenaire est débranché du réseau, le connect va bloquer mon thread le temps d'avoir un timeout sur la socket (ça prends plus de 30 secondes) et le pire, c'est que le thread qui est en attente d'entrées/sorties ne rends pas la main. mon application reste donc bloquée pendant 30 secondes, alors que le temps de cycle ne doit pas dépasser 10 secondes (plus ou moins temps réel)

J'ai tenté de jouer avec SO_SNDTIMEO mais rien n'y fait, voici mon code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
int tcp_init_client(char *server_name, unsigned short port, SOCKET *cli_sock, int required_timetout)
{
  int                 errnr = -999;
  unsigned int        addr;
  int                 socket_type = TCP_SOCKET_TYPE, ret;
  struct sockaddr_in  server;
  struct hostent      *hp;
  int                 timeout;
  time_t t;
  char strtime[255];
 
  if (port == 0)
  {
    return -1;
  }
 
    hp = gethostbyname(server_name);
 
 
  if (hp == NULL)
  {
 
    errnr = WSAGetLastError();
 
    trc_msg(ERR_TCP, INDENT_0, ERR, 0, "TCP Client: Cannot resolve address [%s]: Error %d", server_name, errnr);    
    return -1;
  }
 
  /* Copy the resolved information into the sockaddr_in structure */
  memset(&server, 0, sizeof(server));
  memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
  server.sin_family = hp->h_addrtype;
  server.sin_port = htons(port);
 
  *cli_sock = socket(AF_INET, socket_type, 0);  /* Open a socket */
  if (*cli_sock == INVALID_SOCKET)
  {
    errnr = WSAGetLastError();
    trc_msg(ERR_TCP, INDENT_0, ERR, 0, "TCP Client: Error Opening socket: Error %d", errnr);
    return -1;
  }
 
  timeout = required_timetout;
  /*We set a send timeout in order to detect that a client is down*/
 
  if (ret = setsockopt(*cli_sock, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout)))
  {
    errnr = WSAGetLastError();
 
    trc_msg(ERR_TCP, INDENT_0, ERR, 0, "Setsockopt SO_RCVTIMEO failed with error:%d", errnr);
  }
 
 
  trc_msg(ERR_TCP, INDENT_0, INFO, 0, "TCP Client connecting to: %s (%d)", hp->h_name);
 
  t = (time(NULL) + 0);
  strftime(strtime, 255, "%Y%m%d %X\t", my_localtime(&t));
  printf("\n time before:%s", strtime);
  if (connect(*cli_sock, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR)
  {
    errnr = WSAGetLastError();
 
    t = (time(NULL) + 0);
    strftime(strtime, 255, "%Y%m%d %X\t", my_localtime(&t));
    printf("\n time after:%s", strtime);
    if (!quietmode)
      trc_msg(ERR_TCP, INDENT_0, ERR, 0, "TCP Client connect %s (%d) failed: %d", hp->h_name, port, errnr);
    return -1;
  }   
  return 0;
}
voilà, je n'ai pas d'erreur lors du setsockopt()
par contre je n'arrive pas à lire SO_RCVTIMEO avec getsockopt(), chaque fois il me donne l'erreur WSAEFAULT 10014

D'après mes recherches, fixer SO_SNDTIMEO ou SO_RCVTIMEO ner fonctionne pas des masses.

Je cherche donc désespérément une solution.

J'accepetrais volontier d'utiliser un select, mais comment faire sur une socket client?

merci de toutes vos propositions