IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web & réseau Delphi Discussion :

Disconnecting Socket Error n°10053 : Software caused connection abort.


Sujet :

Web & réseau Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut Disconnecting Socket Error n°10053 : Software caused connection abort.
    Bonjour à tous,

    J'ai un programme client Windev qui communique avec un serveur de socket Delphi.
    Schéma standard, mon client demande la connexion au serveur si ça fonctionne il écrit dans la socket et là ma fonction Réception prend le relai et attends pendant 10 s. la réponse. Si au bout de 10s. la variable qui lit la socket est vide alors j'ai un message "Erreur en réception". Seulement j'ai régulièrement des "erreurs en réception" et je n'arrive pas à trouver la solution ni à la reproduire systématiquement. Et là bim j'ai pu logger côté Delphi l'erreur :

    "Disconnecting Socket Error n°10053 : Software caused connection abort." sachant que cette erreur c'est moi qui la gère dans la procédure :
    ServerSocketClientError :

    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
    procedure TMainForm.ServerSocketClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
     
    var
      ErrorMsg : String;
    begin
     
      // Définition du message d'erreur en fonction du code d'erreur
      Case ErrorCode Of
        10013 : ErrorMsg := 'Permission Refusée.';
        10014 : ErrorMsg := 'Mauvaise adresse.';
        10022 : ErrorMsg := 'Arguments Invalides.';
        10024 : ErrorMsg := 'Trop de fichiers ouverts.';
        10035 : ErrorMsg := 'Resource temporarily unavailable.';
        10036 : ErrorMsg := 'Operation en cours.';
        10037 : ErrorMsg := 'Operation déjà en cours.';
        10038 : ErrorMsg := 'Socket operation On non-socket.';
        10039 : ErrorMsg := 'Destination address required.';
        10040 : ErrorMsg := 'Message trop long.';
        10041 : ErrorMsg := 'Protocol wrong Type For socket.';
        10042 : ErrorMsg := 'Bad protocol option.';
        10043 : ErrorMsg := 'Protocol Not supported.';
        10044 : ErrorMsg := 'Socket Type Not supported.';
        10045 : ErrorMsg := 'Operation Not supported.';
        10046 : ErrorMsg := 'Protocol family Not supported.';
        10047 : ErrorMsg := 'Address family Not supported by protocol family.';
        10048 : ErrorMsg := 'Address already In use.';
        10049 : ErrorMsg := 'Cannot assign requested address.';
        10050 : ErrorMsg := 'Network Is down.';
        10051 : ErrorMsg := 'Network Is unreachable.';
        10052 : ErrorMsg := 'Network dropped connection On reset.';
        10053 : ErrorMsg := 'Software caused connection abort.';
        10054 : ErrorMsg := 'Connection reset by peer.';
        10055 : ErrorMsg := 'No buffer space available.';
        10056 : ErrorMsg := 'Socket Is already connected.';
        10057 : ErrorMsg := 'Socket Is Not connected.';
        10058 : ErrorMsg := 'Cannot send after socket shutdown.';
        10060 : ErrorMsg := 'Connection timed Out.';
        10061 : ErrorMsg := 'Connection refused.';
        10064 : ErrorMsg := 'Host Is down.';
        10065 : ErrorMsg := 'No route To host.';
        10067 : ErrorMsg := 'Too many processes.';
        10091 : ErrorMsg := 'Network subsystem Is unavailable.';
        10092 : ErrorMsg := 'WINSOCK.DLL version Out Of range.';
        10093 : ErrorMsg := 'Successful WSAStartup Not yet performed.';
        10094 : ErrorMsg := 'Graceful shutdown In progress.';
        11001 : ErrorMsg := 'Host Not found.';
        11002 : ErrorMsg := 'Non-authoritative host Not found.';
        11003 : ErrorMsg := 'This Is a non-recoverable error.';
        11004 : ErrorMsg := 'Valid name, no data Record Of requested Type.';
      Else
        // erreur inconnue
        ErrorMsg := 'Unknown socket error.';
      End;
     
      // mise en forme de la signification de l'erreur
        ErrorMsg := 'Socket Error n°' + IntToStr(ErrorCode) + ' : ' + ErrorMsg;
        // l'erreur est traitée
        ErrorCode := 0;
        // définition du type d'erreur
        Case ErrorEvent Of
            eeSend       : ErrorMsg := 'Writing '       + ErrorMsg;
            eeReceive    : ErrorMsg := 'Reading '       + ErrorMsg;
            eeConnect    : ErrorMsg := 'Connecting '    + ErrorMsg;
            eeDisconnect : ErrorMsg := 'Disconnecting ' + ErrorMsg;
            eeAccept     : ErrorMsg := 'Accepting '     + ErrorMsg;
        Else
            // erreur inconnue
            ErrorMsg := 'Unknown ' + ErrorMsg;
        End;
        LogErreur(ErrorMsg);
    end;
    J'ai fouillé un peu sur le net mais ça ne m'a pas trop aidé...est ce que cette erreur vous parle ?
    Merci d'avance
    Windows XP
    Delphi 7

    WinDev Mobile 17

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Ton histoire de 10s, ton client, une fois cela délai dépasserait ne ferait pas un close de la connection, il se ferme tout seul ou ferme juste la connexion ?

    Tu es en Blocking = thread, ou NotBlocking = OnRead
    Sur le serveur, évite de faire trop de traitement dans OnRead, le mieux c'est de recevoir le buffer, de le mettre dans une ThreadList, et avec un TEvent,
    tu réveille un thread qui lit cette ThreadList

    Tant que le OnRead tourne, les messages suivants s'accumule dans le tampon TCP de la carte réseau (et celui de windows)

    Ensuite, le parsage des message est géré par ce thread, il peut se charger de lire la DB ou autre puis de générer un message de réponse, perso, je sépare tout cela dans plusieurs thread
    Cela permet ainsi de gérer plusieurs clients et selon leur demande de les traiter séquentiellement (plus prudent avec une DB) ou parallèlement pour des taches qui ne risque pas de collision

    Pense que le OnRead peut recevoir un paquet "groupé" de message d'un client, si cela dépasse 8Ko, tu peux avoir le début d'un message à la fin du buffer et son début dans les 8Ko suivant, pense à bien gérer cela !

    Je te le dit car j'ai eu un programme tiers qui le gérait mal, et j'ai du de mon côté ralentir l'envoi de certains messages (je pouvais en envoyer 40 à la seconde, du coup, il avait près de 25 messages d'un coup, il était incapable de les traiter)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut
    Une fois le délai de réception dépassé je ferme la connexion socket pour que l'user puisse réessayer d'envoyer la trame ==> ce qui amène à lancer une nouvelle connexion.
    Pour le servertype de ma socket je suis en stNonBlocking.
    Dans le OnRead, je fais juste un appel de fonction en fonction du type de message reçu.
    Windows XP
    Delphi 7

    WinDev Mobile 17

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par juju1988 Voir le message
    Une fois le délai de réception dépassé je ferme la connexion socket pour que l'user puisse réessayer d'envoyer la trame ==> ce qui amène à lancer une nouvelle connexion.
    C'est ça ton problème, pourquoi fermer\ouvrir en permanence ?
    Tu devrais revoir ton protocole, en TCP\IP on est averti en cas d'erreur de reception, le Send\Write va le signaler
    Tu devrais mettre en place un Keep Alive, les clients et le serveur envoie une trame minimale toutes les 5 secondes, juste pour assurer que la connexion est ouverte mais aussi que les programmes (et threads) fonctionnent correctement.

    Dès que l'on envoie un message, cela reprend le compteur de Keep Alive à zéro
    Si le Keep Alive n'est pas maintenu, reconnexion !

    Tu peux utiliser un système de ACK\NAK de TON protocol en surcouche de ceux du TCP\IP, le but du ACK\NAK est d'informer les parties connectées que les messages échangés contiennent des données correctes (type, plage de valeur, ...)

    l'émetteur envoie un Message,
    le recepteur analyse le message (sans le traiter) et renvoie un ACK si le format de la trame est correct ou NAK si il ne l'a comprend pas juste d'un point de vue format
    Si ACK : le recepteur traite le message
    Si NAK : l'émetteur reconstruit la trame et l'a renvoie, un second NAK indiquerait un problème dans ton packer\parser de message,
    Si pas de confirmation, tu peux considérer que le recepteur est planté, tu peux tenter une reconnexion dans ce cas uniquement

    le recepteur a traité le message et envoie une réponse à l'émetteur, cette réponse indique si le traitement est un succès ou pas !
    cette réponse est gérée aussi par du ACK\NAK

    J'ai des programmes tournant plus de 12h connecté (Server sur Win2K et clients sur NT4-Venturcom) et même plus jusqu'à 72h sans changer de connexion, le BDE plantait lamentablement après plus de 10Millions d'opérations bien avant les sockets !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut
    Parce que c'est ce qui m'a été demandé de faire. J'envoi une trame (Ecrit socket) j'attends pendant 10 secondes sa réponse... (fonction réception et je traite en affichage).

    Comment utiliser du ACK/NAK ?
    Windows XP
    Delphi 7

    WinDev Mobile 17

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Donc, tu n'y peux rien, ton client se déconnecte, le serveur signale cela par une erreur, tu l'interceptes, tu la loggues, que veux tu faire de plus !

    Il est vrai qu'il serait préférable d'avoir un OnClientDisconnect, regarde sur ton client, si il y a une méthode "propre" de déconnexion, je suppose que tu utilises SocketFerme
    Test avec un client Delphi sur un Serveur Delphi, et un client WD sur un server WD, voir le comportement, tu pourras savoir de quel côté est le problème !

    Mon expérience en TCP+Multithread sur WD fut une catastrophe !

    En Windev 5.5 (mai 2002), 1ère fonction TCP, totalement instable

    En Windev 7.0, seul le mode SocketTailleDébut fonctionnait sinon cela plantait sur #0 dans la donnée considéré à tord comme une fin de ligne, super pour échanger un binaire, pas de chance mon boss de l'époque me sort la 7.5 beta qui corrigeait le bug ! Grrr ! Obliger de continuer avec WD !

    En Windev 7.5, après avoir pas mal codé, j'ai constaté une installabilité des sockets, PC Soft après quelques échanges m'avait répondu : "Windev ne peut répondre à votre problèmatique pointu", tu parles, deux sockets server, pointu,
    Le problème était que WD pouvait affecté à deux sockets (deux ports différents donc deux thread de listen) le même ID à cause d'un client trop rapide ouvrant plusieurs clients sur plusieurs ports en moins de 10ms (semble que c'était le temps de latence naturelle de la machine virtuelle WD lors des interactions avec l'OS)

    J'espère qu'en 10 versions cela c'est amélioré !

    J'ai proposé Delphi 6 comme language de remplacement à WD 7.5, et cela fonctionnait à merveille face aux clients codés en VSC++ !



    ACK/NAK c'est un mécanisme de contrôle
    Positive acknowledgement (ACK) = OK, j'ai bien reçu et compris ta demande
    Negative acknowledgement (NAK) = KO, je n'ai pas compris ta demande

    C'est à toi de le coder dans ton propre protocole !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut
    Ah de toute façon quand tu fais pas du 100% Windev c'est rare que PC soft te réponde positivement...ça vient forcément de l'autre logiciel lol ^^
    Merci pour ton aide.
    Je vais voir ce que je peux faire je te tiens au courant
    Windows XP
    Delphi 7

    WinDev Mobile 17

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ton histoire de 10s, ton client, une fois cela délai dépasserait ne ferait pas un close de la connection, il se ferme tout seul ou ferme juste la connexion ?

    Tu es en Blocking = thread, ou NotBlocking = OnRead
    Sur le serveur, évite de faire trop de traitement dans OnRead, le mieux c'est de recevoir le buffer, de le mettre dans une ThreadList, et avec un TEvent,
    tu réveille un thread qui lit cette ThreadList

    Tant que le OnRead tourne, les messages suivants s'accumule dans le tampon TCP de la carte réseau (et celui de windows)

    Ensuite, le parsage des message est géré par ce thread, il peut se charger de lire la DB ou autre puis de générer un message de réponse, perso, je sépare tout cela dans plusieurs thread
    Cela permet ainsi de gérer plusieurs clients et selon leur demande de les traiter séquentiellement (plus prudent avec une DB) ou parallèlement pour des taches qui ne risque pas de collision

    Pense que le OnRead peut recevoir un paquet "groupé" de message d'un client, si cela dépasse 8Ko, tu peux avoir le début d'un message à la fin du buffer et son début dans les 8Ko suivant, pense à bien gérer cela !

    Je te le dit car j'ai eu un programme tiers qui le gérait mal, et j'ai du de mon côté ralentir l'envoi de certains messages (je pouvais en envoyer 40 à la seconde, du coup, il avait près de 25 messages d'un coup, il était incapable de les traiter)
    Bonjour Shai justement j'ai eu le problème sur des messages de plus de 8 ko comment as tu résolu ce problème ?

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par aroslide Voir le message
    Bonjour Shai justement j'ai eu le problème sur des messages de plus de 8 ko comment as tu résolu ce problème ?
    Tu aurais du créer une autre discussion et mettre celle-ci en lien
    Cette discussion est déjà pour Juju !

    Je stockais mes buffers les un à la suite des autres
    C'est un autre thread qui allait lire ce buffer pour extraire les données exploitable
    Cela a fonctionné pour
    - un protocol genre CSV en streaming, en gros lisait une ligne commençant toujours par ++ jusqu'au CRLF
    et laissait tout ce qui était après dans le buffer, à l'itération suivante, je lisais une nouvelle ligne, tant que la ligne n'était pas complète,
    je ne vidais pas le buffer pour que le socket puisse le compléter, en TCP\IP tu reçois toujours les trames dans l'ordre et toutes !
    - un protocol binaire commençant par FD et terminant par FE plus une structure de header\body\footer qui permettait de vérifier la taille, un checksum ...
    idem, je cherchais d'abord un header (taille fixe débutant par FD), si le FE était bien à la position prévue, je pouvais extraire le packet,
    ce qui était après le FEF était le packet suivant, et cela pouvait recommencer !

    je précise que cette technique a été utilisé dans des programmes échangeant 5 à 20 messages par seconde et cela pendant 8h (4 phase de 2h),
    le programme utilisant IBX pouvait tourner plusieurs jours sans soucis,
    l'autre en BDE\Pdx plantait au bout de 24h non stop (EDBEEngineError, et fichier PDX corrompu) mais la partie protocole ne souffrait pas de problème

    Voici des liens vers le code de la version binaire, écrit quand j'étais encore à l'école, donc rien de bien compliquer surtout que c'est à peine si je savais coder en objet
    Socket et multithread
    Re: TClientSocket et IRC
    Re: Transfert Timage TCP/IP
    Envoi donnes par socket
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Je suis d'accord avec toi mais j'ai pas mal bossé sur un serveur utilisant les sockets asynchrones et là j'avais utilisé un système de buffers me permettant de séparer les commandes de la gestion du chat du blabla classique des utilisateurs; au passage un grand merci au site de felix colibri qui m'a permis de vraiment bien comprendre ce principe par contre arrivé à environ 2000 utilisateurs entre leurs déconnections et leurs reconnections et les données à traiter le buffer était vraiment saturé et prenait une partie des messages pour les rajouter aux autres ce qui parfois donnait des résultats assez étranges (une partie des messages étaient tronqués ou additionnés à d'autres messages). hélas j'ai eu beau chercher; pas de solutions à mon problème pourtant j'ai essayé pas mal de choses pour gérer le buffer threads, semaphore, mutex rien à faire .... même erreur.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 27/11/2014, 15h30
  2. Réponses: 0
    Dernier message: 25/06/2012, 15h17
  3. Erreur "Software caused connection abort: recv failed"
    Par zatari dans le forum Développement Web en Java
    Réponses: 2
    Dernier message: 21/08/2011, 11h44
  4. Réponses: 1
    Dernier message: 19/01/2010, 21h20
  5. Réponses: 1
    Dernier message: 02/06/2006, 10h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo