[ eVC++ ] [socket] Eviter les envois de données "dans la nature"
Eviter les envois de données "dans la nature" [ eVC++ ] [socket] - C++ - Programmation
MarshPosté le 17-11-2005 à 12:28:22
Bonjour,
je suis actuellement en train de retoucher un programme pour PocketPC (PPC). Nous rencontrons des pertes de connexion régulières (ca passe par wifi). Ca se traduit par un lag infini et le PPC est bloqué (socket synchrone, attend une réponse du serveur). On reboot alors le PPC mais le serveur lui reste a l'état "connecté". Il faut donc également repasser le serveur en mode "écoute".
Pour éviter les désagréments de l'utilisateur, j'essaye d'automatiser la reconnexion sur le PPC. (je ne parle pas du serveur, admettons qu'il soit en écoute dès que la connexion avec le PPC est perdue).
Voici le code du PPC pour envoyer un message au serveur (requête sql). Comme je fonctionne avec des sockets synchrones, chaque message envoyé attends une réponse du serveur
Code :
bool connexion::send_msg(CString MSG)
{
if((snd_msg(MSG))==false) //envoi du MSG
{
MessageBox(NULL,TEXT("Erreur à l'envoi. Pointez OK pour vous reconnecter" ),TEXT("Erreur" ),MB_OK);
//si la reconnexion est un succès on réenvoie le message
if (reconnect()==true)
{
send_msg(MSG);
returntrue;
}
else
{
MessageBox(NULL,TEXT("La reconnexion a echoué, contactez le service informatique !" ),TEXT("Erreur" ),MB_OK);
returnfalse;
}
}
if((rcv_msg())==false) //réception des données/remplissage du recordset
{
MessageBox(NULL,TEXT("Erreur à la reception. Pointez OK pour vous reconnecter" ),TEXT("Erreur" ),MB_OK);
//si la reconnexion est un succès on réenvoie le message
if (reconnect()==true)
{
send_msg(MSG);
returntrue;
}
else
{
MessageBox(NULL,TEXT("La reconnexion a echoué, contactez le service informatique !" ),TEXT("Erreur" ),MB_OK);
returnfalse;
}
}
returntrue;
}
Si l'envoi de mon message échoue, je lance la reconnexion puis je réenvoie le message. Si la réception de la réponse échoue, je lance la reconnexion puis je réenvoie le message.
Dans ce dernier cas, je prend donc le risque d'envoyer deux fois le même message pour obtenir une seule réponse et donc foutre en l'air ma base de données derrière.
Par exemple : envoi de : insert bidule into machin --> l'envoi a été effectué reception : erreur reconnexion envoi de : insert bidule into machin --> l'envoi a été effectué reception : ecriture ok --> la reception a été effectuée
Et là on peux se poser deux questions par rapport à l'erreur obtenue à la 1ère réception: - l'envoi de données est-il parvenu jusque au serveur ? (est-on connecté au serveur ?) - le serveur a-t-il renvoyé un accusé ? (le serveur s'est-il planté en cours de route ?)
J'ai donc peut être inseré deux fois la valeur bidule dans ma table parceque mon premier accusé n'est pas arrivé à destination mais que la requete a bien été executée.
En lisant la doc, on sais que si recv renvoie 0, la connexion n'est plus disponible, je l'ai testé (en fermant le serveur) et ca fonctionne. par contre pour send (avec le serveur fermé), la valeur 0 n'est jamais renvoyée (normal c'est ps dans la doc) et SOCKET_ERROR n'est JAMAIS retourné ! Donc j'envoie des données qui n'arrivent jamais et je n'en suis pas informé ...
Citation :
If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
Citation :
If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
Marsh Posté le 17-11-2005 à 12:28:22
Bonjour,
je suis actuellement en train de retoucher un programme pour PocketPC (PPC).
Nous rencontrons des pertes de connexion régulières (ca passe par wifi).
Ca se traduit par un lag infini et le PPC est bloqué (socket synchrone, attend une réponse du serveur).
On reboot alors le PPC mais le serveur lui reste a l'état "connecté".
Il faut donc également repasser le serveur en mode "écoute".
Pour éviter les désagréments de l'utilisateur, j'essaye d'automatiser la reconnexion sur le PPC.
(je ne parle pas du serveur, admettons qu'il soit en écoute dès que la connexion avec le PPC est perdue).
Voici le code du PPC pour envoyer un message au serveur (requête sql).
Comme je fonctionne avec des sockets synchrones, chaque message envoyé attends une réponse du serveur
Si l'envoi de mon message échoue, je lance la reconnexion puis je réenvoie le message.
Si la réception de la réponse échoue, je lance la reconnexion puis je réenvoie le message.
Dans ce dernier cas, je prend donc le risque d'envoyer deux fois le même message pour obtenir une seule réponse et donc foutre en l'air ma base de données derrière.
Par exemple :
envoi de : insert bidule into machin --> l'envoi a été effectué
reception : erreur
reconnexion
envoi de : insert bidule into machin --> l'envoi a été effectué
reception : ecriture ok --> la reception a été effectuée
Et là on peux se poser deux questions par rapport à l'erreur obtenue à la 1ère réception:
- l'envoi de données est-il parvenu jusque au serveur ? (est-on connecté au serveur ?)
- le serveur a-t-il renvoyé un accusé ? (le serveur s'est-il planté en cours de route ?)
J'ai donc peut être inseré deux fois la valeur bidule dans ma table parceque mon premier accusé n'est pas arrivé à destination mais que la requete a bien été executée.
Voici un boût de code pour mes envois de message
et ici la reception
En lisant la doc, on sais que si recv renvoie 0, la connexion n'est plus disponible, je l'ai testé (en fermant le serveur) et ca fonctionne.
par contre pour send (avec le serveur fermé), la valeur 0 n'est jamais renvoyée (normal c'est ps dans la doc) et SOCKET_ERROR n'est JAMAIS retourné !
Donc j'envoie des données qui n'arrivent jamais et je n'en suis pas informé ...
If no error occurs, send returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
Une idée ?
Message édité par jeoff le 17-11-2005 à 12:32:56