Bonsoir,
Je viens ici un peu dnas le déséspoire mais je doute réellement trouver une réponse.

Je fais une architecture client/serveur avec boost. J'ai suivi le tuto du site + d'autre afin de m'instruire (tres tres instructif d'ailleur).
Je dev mon bouzin, et effectue quelques tests.
Et la horreur, mon client arrive a se connecter, le serveur le voi, je balance ems thread de io_service.run(), de mes classes, etc...
Mais a l'init de la connection, le client a une erreur lors du premier waitData() et retourne une erreur qui semble etre (apres moult analyse de boost)
bad_file_descriptor affiche (SYSTEM:9) dans un std::cout<<.
Bon ceci etant, je l'ignore car bon ca ne semble pas trop géner...
J'essaye d'envoyer un message du cleint au serveur, ca passe.
Du serveur au client, passe aussi.
Mais si je fais les deux, pas ca fouare, (retourne header invalide dans ma fonction de lecture)...Ce qui est assez génant!
ensuite, pour voir si le client se déconnecte, je capte l'erreur end_of_file.ca marche niquel, hormis que mon serveur detecte autant de EOF que de message recu depuis sont init...

Tout ceci est assez genant et facheu. J'imagine bien qu'en résolvant l'histoire de system:9 ca devraita llez mieu.
Je pense que l'erreur viens peut etre des io_service threadé ou autre...
Voici le code (attention paté)

et Merci d'avance....
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
SERVEUR.CC
 
Serveur::~Serveur()
{ 
  cout<<printInf()<<"DELETE"<<endl;
}
 
 
Serveur::Serveur(int id,TcpServeurMaitre* master,connection_ptr new_connection):NetworkWidget(id,new_connection),my_master(master)
{
  cout<<printInf()<<"Serveur démarré ..."<<endl;
}
 
 
// handler de reception de messages
void Serveur::traiterDonnees()
{
  short protocole= (my_network->getProtocole());
 
  // my_network->toTarget(5,((short)3));
 
  if( protocole == -1)
    return;
 
  if( Protocole::ping == protocole )
    {
 
    }
  else if( Protocole::connexion == protocole )
    {
      //  traiterConnection(data);
    }
  else
    cout<<"[[unknown datas]]"<<endl;
 
}
 
 
void Serveur::traiterDeconnection()
{
  NetworkWidget::traiterDeconnection();
  my_master->finServeur(this);
 
}
 
void Serveur::run()
{ 
  cout<<"<#> I'm waiting"<<endl;
  sleep(1);
  while(my_network->getPower())
    {
      cout<<printInf()<<"::run()"<<endl;
      my_network->toTarget(42,((short)10));
      sleep(2);
    }
 
 
}
void Serveur::deconnection()
{
  //   Node::deconnexionRecues();
  my_master->finServeur(this);
 
}
client
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 
 
 
 
Client::Client(string ip, int port,string user, string passwd)
{
 
  try
    {
      serveurIP = ip;
      serveurPort = port;
      createConnection(connection_ptr(new tcp_connection(m_io_service)));
 
      tcp::endpoint endpoint(boost::asio::ip::address::from_string(ip), port);
       my_network->connectToTarget(endpoint);
 
     }
  catch (std::exception& e)
    {
      std::cerr << "Exception: " << e.what() << std::endl;
    }
 
 
  //coToServ(ip,port,Protocole::TCP);
 
  /*
  if(  target->waitForConnected() && (target->state() ==( QAbstractSocket::ConnectedState )))
    {
      connecte();
    }
  if(power)
    {
      dde_connection(user,passwd,1);
      if(target->waitForReadyRead(30000))//15secondes a atrendre la reponse
	{
	  cout<<"c'est bon"<<endl;
	}
      else
	{
	  power=false;
	  cout<<"pas bon"<<endl;
	}
	}*/
  cout<<printInf()<<"Création Client"<<endl;
}
 
void Client::run()
{
  boost::thread t(boost::bind(&boost::asio::io_service::run, &m_io_service));
  cout<<"<#> I'm waiting"<<endl;
  //  sleep(3);
 
  while(my_network->getPower())
    {
          my_network->toTarget(442,((short)10));
       cout<<"Client::run()"<<endl;
       sleep(2);
    }
  /*
    sleep(1);
  while(power)
    {
      //Opération pour vérifier l'etat du client, si il y a des message sur le socket, etc...
      if(target->bytesAvailable()>(int)sizeof(short))
	this->donneesRecues();
 
      if((target->state() == QAbstractSocket::UnconnectedState) || target->waitForDisconnected(20))
	{
	this->deconnexionRecues();
	}
      
      cout<<"............"<<endl;
 
    }
   cout<<"END OF THREAD"<<endl;
  //Le client c'est deconnecté, on effectue les actions de sortie
  target->deleteLater();
  cout<<"END OF THREAD"<<endl;
  */
       cout<<"EDNNNNNNNNN"<<endl;
  m_io_service.post(boost::bind(&Client::traiterDeconnection, this));
  sleep(3);
  t.join();
}
 
void Client::do_close()
{
  my_network->close();
 
}
// On a reu un paquet (ou un sous-paquet)
void Client::traiterDonnees()
{
  cout<<printInf()<<"Donnée En traitement"<<endl;
NetworkModule
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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 
 
 
NetworkModule::NetworkModule(int id,connection_ptr new_connection,NetworkWidget* parent):my_connection(new_connection)
{
  my_id = id;
  power = true;
  my_parent = parent;
  cout<<printInf()<<"] Création du module Network"<<endl;
  cout<<printInf()<<"Module et connection démarrés ..."<<endl;
  protocole = -1;
}
 
string NetworkModule::printInf()
{
  ostringstream oss;
  oss<<"[NetworkModule N"<<my_id<<"] ";
  return oss.str();
}
 
void NetworkModule::deconnexionRecues()
{
  cout<<printInf()<<"Deconnexion recue..."<<endl;
  power=false;
 
 
}
 
 
short NetworkModule::getProtocole()
{
  return protocole;
 
}
 
 
void NetworkModule::connectToTarget(tcp::endpoint& endpoint)
{
  tcp::socket& sock = my_connection->socket();
  sock.async_connect(endpoint,boost::bind(&NetworkModule::handle_connect, this,
		boost::asio::placeholders::error));
  std::cout<<&sock<<std::endl;
 
 
}
 
void NetworkModule::handle_connect(const boost::system::error_code &error)
{
  //y a t'il eu une erreur
  if(!error)
    {
      std::cout<<"NetworkModule Connecté au client"<<std::endl;
      power=true;
      sleep(3);
      waitData();
    }
  else
    {
      std::cout<<"ERREUR NetworkModule::connectToTarget <--> handle_connect"<<std::endl;
      std::cout<<"Deconnection du module..."<<std::endl;
      power=false;
    }
 
}
 
void NetworkModule::toTarget(int i,short protocole_to_use)
{
  std::cout<<&(my_connection->socket())<<std::endl;
  my_connection->async_write(i,boost::bind(&NetworkModule::toTargetFinished, shared_from_this(),boost::asio::placeholders::error));
  std::cout<<&(my_connection->socket())<<std::endl;
 
}
 
 
template <typename T>
void NetworkModule::toTarget(T& t,short& protocole_to_use)
{
 
  my_connection->async_write(t,boost::bind(&NetworkModule::toTargetFinished, shared_from_this(),boost::asio::placeholders::error));
 
 
}
 
void NetworkModule::toTargetFinished(const boost::system::error_code &error)
{
  if(!error)
    {
      waitData();
    }
  else if(error==boost::asio::error::invalid_argument)
    {
      std::cerr<<printInf()<<"Erreur a l'envoi de donnée."<<std::endl;
      waitData();
    }
  else
    {
      power=false;
    }
 
 
}
// handler de reception de messages
void NetworkModule::donneesRecues(const boost::system::error_code &error)
{
  if(!error)
    {
      cerr<<"plop"<<endl;
      waitData();
      my_parent->traiterDonnees();
 
    }
  else if(error==boost::asio::error::invalid_argument)
    {
      cerr<<printInf()<<"Header invalide. Paquet endommagé ou incomplé."<<endl;
      waitData();
      return;
    }
  else if(error==boost::asio::error::eof)
    {
      cerr<<"Fin de connection"<<endl;
      my_parent->traiterDeconnection();
    }
  else if(error==boost::system::posix_error::bad_file_descriptor)
    {
      cerr<<"NetworkModule::donneesRecues::bad_file_descriptor"<<endl;
    }
  else//autre erreur, on va alors préférer se déconnecté { a gerer plus tard pour rajouter des traitement au erreurs car c'est plus sympa}
    {
      cout<<error<<" !!!!!!ERROR!!!!!!"<<endl;
      std::cout<<&(my_connection->socket())<<std::endl;
      //      parent->traiterDonnees(archive,protocole);
      //std::cout<<"NetworkModule : donnees bien recues :) "<<std::endl;
      cerr<<printInf()<<"une erreur est survenu dans le module Network los de donneesRecues"<<endl;
      my_parent->traiterDeconnection();
 
    }
}
 
 
void NetworkModule::waitData()
{
//on attend l'arrivé de donnée
//On passe la fonction DonnéeRecues() en paramètre, qui sera appelé si il y a des messages recues
  my_connection->async_read(m_message,protocole,boost::bind(&NetworkModule::donneesRecues, shared_from_this(),boost::asio::placeholders::error)  );
 
}
 
 
bool NetworkModule::getPower()const
{
  return power;
}
 
 
void NetworkModule::close()
{
  //  my_connection->socket().close();
  power=false;
 
 
}
et tcp_connection (meme que le tuto a 2-3 truc pour l'instant )

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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
 
 
 
class tcp_connection
{
public:
 tcp_connection(boost::asio::io_service& io_service)
   : m_socket(io_service)
  {
  }
 
  boost::asio::ip::tcp::socket& socket()
    {
      return m_socket;
    }
 
  // Ecriture asynchrone sur le socket
  template <typename T, typename Handler>
    void async_write(const T& t, Handler handler)
  {
    // On sérialise.
    std::ostringstream archive_stream;
    boost::archive::text_oarchive archive(archive_stream);
    archive << t;
    m_outbound_data = archive_stream.str();
 
    // On écrit un header.
    std::ostringstream header_stream;
    header_stream << std::setw(header_length)
		  << std::hex << m_outbound_data.size();
    if (!header_stream || header_stream.str().size() != header_length)
      {
	// En cas de problème, on informe l'appelant.
	boost::system::error_code error(boost::asio::error::invalid_argument);
	m_socket.io_service().post(boost::bind(handler, error));
	return;
      }
    m_outbound_header = header_stream.str();
 
    // On écrit les données sérialisées dans le socket.
    std::vector<boost::asio::const_buffer> buffers;
    buffers.push_back(boost::asio::buffer(m_outbound_header));
    buffers.push_back(boost::asio::buffer(m_outbound_data));
    boost::asio::async_write(m_socket, buffers, handler);
  }
 
 
 
  // Lecture asynchrone de données depuis le socket
  template <typename T, typename Handler>
    void async_read(T& t,short& protocole, Handler handler)
  {
    // On récupère le header 
    void (tcp_connection::*f)( const boost::system::error_code&, T&, boost::tuple<Handler>,short&)
      = &tcp_connection::handle_read_header<T, Handler>;
    boost::asio::async_read(m_socket, boost::asio::buffer(m_inbound_header),
			    boost::bind(f,
					this, boost::asio::placeholders::error, boost::ref(t),
					boost::make_tuple(handler),protocole));
  }	
 
 
 
 
  //Interprétation du header
  template <typename T, typename Handler>
    void handle_read_header(const boost::system::error_code& e,
			    T& t, boost::tuple<Handler> handler,short& protocole)
  {
    if (e)
      {
	boost::get<0>(handler)(e);
      }
    else
      {
	// Détermine la longueur du vrai message
	std::istringstream is(std::string(m_inbound_header, header_length));
	std::size_t m_inbound_datasize = 0;
	if (!(is >> std::hex >> m_inbound_datasize))
	  {
	    // Header non valide, on informe la fonction appelante
	    boost::system::error_code error(boost::asio::error::invalid_argument);
	    boost::get<0>(handler)(error);
	    protocole=-1;
	    return;
	  }
 
	// On récupère les données
	m_inbound_data.resize(m_inbound_datasize);
 
 
 
	void (tcp_connection::*f)(
				  const boost::system::error_code&,
				  T&, boost::tuple<Handler>)
	  = &tcp_connection::handle_read_data<T, Handler>;
	boost::asio::async_read(m_socket, boost::asio::buffer(m_inbound_data),
				boost::bind(f, this,
					    boost::asio::placeholders::error, boost::ref(t), handler));
 
 
 
 
 
 
	/*	void (tcp_connection::*f)(
				  const boost::system::error_code&,
				  T&, boost::tuple<Handler>,short&)
	  = &tcp_connection::handle_read_protocole<T, Handler>;
	boost::asio::async_read(m_socket, boost::asio::buffer(m_inbound_data),
				boost::bind(f, this,
					    boost::asio::placeholders::error, boost::ref(t), handler,protocole));
	*/
      }
  }
 
 
 
 
  template <typename T, typename Handler>
    void handle_read_protocole(const boost::system::error_code& e,
			       T& t, boost::tuple<Handler> handler,short& protocole)
  {
        if (e)
      {
	boost::get<0>(handler)(e);
      }
    else
      {
	// Détermine la longueur du vrai message m_inbound_protocole
	std::istringstream is(std::string(m_inbound_protocole,protocole_lenght));
	int m_inbound_datasize = 0;
	if (!(is >> m_inbound_datasize))
	  {
 
	    boost::system::error_code error(boost::asio::error::invalid_argument);
	    protocole=-1;
	    boost::get<0>(handler)(error);
	    return;
	  }
 
	void (tcp_connection::*f)(
				  const boost::system::error_code&,
				  T&, boost::tuple<Handler>)
	  = &tcp_connection::handle_read_data<T, Handler>;
	boost::asio::async_read(m_socket, boost::asio::buffer(m_inbound_data),
				boost::bind(f, this,
					    boost::asio::placeholders::error, boost::ref(t), handler));
      }
  } 
 
 
  // Les données reçues, on les désérialise
  template <typename T, typename Handler>
    void handle_read_data(const boost::system::error_code& e,
			  T& t, boost::tuple<Handler> handler)
  {
    if (e)
      {
	boost::get<0>(handler)(e);
      }
    else
      {
	// On extrait
	try
	  {
	    std::string archive_data(&m_inbound_data[0], m_inbound_data.size());
	    std::istringstream archive_stream(archive_data);
	    boost::archive::text_iarchive archive(archive_stream);
	    archive >> t;
 
	  }
	catch (std::exception& /*e*/)
	  {
	    // En cas d'échec
	    boost::system::error_code error(boost::asio::error::invalid_argument);
	    boost::get<0>(handler)(error);
	    return;
	  }
 
	// On informe l'appelant que tout s'est bien passé.
	boost::get<0>(handler)(e);
      }
  }
 
 
 
 
 private:
  // le socket membre sous jacent.
  boost::asio::ip::tcp::socket m_socket;
 
  // Taille de l'header.
  enum { header_length = 8 };
  static const int protocole_lenght=1;
  std::string m_outbound_protocole;
  std::string m_outbound_header;
  std::string m_outbound_data;
  char m_inbound_header[header_length];
  char m_inbound_protocole[protocole_lenght];
  std::vector<char> m_inbound_data;
};
 
typedef boost::shared_ptr<tcp_connection> connection_ptr;