Mauvaise récéption d'info.

Signaler
Messages postés
29
Date d'inscription
lundi 11 janvier 2010
Statut
Membre
Dernière intervention
19 septembre 2010
-
Messages postés
29
Date d'inscription
lundi 11 janvier 2010
Statut
Membre
Dernière intervention
19 septembre 2010
-
Bonjour,

Voilà je travaille actuellement sur le dévellopement d'une interface Graphique simple qui ouvre une socket client et se connecte au serveur par TCP/IP.

Dans un sous menu de config. je met le code suivant :
Private Sub BtnConnexion_Click()
ESECO.Socket.Connect txtIP.Text, txtPort.Text
txtResult.Text = "Connexion avec " &ESECO.Socket.RemoteHostIP 'Affciher l'adresse IP du Serveur 
BtnConnexion.Enabled = False ' Bouton Connexion inactif
CmdDeconnexion.Enabled = True 'Bouton Déconnexion Actif
End Sub
________________________________________________________________

Private Sub CmdDeconnexion_Click()
ESECO.Socket.Close
txtResult.Text = "Connexion terminée !"
BtnConnexion.Enabled = True
CmdDeconnexion.Enabled = False
End Sub 


Et le code de ma fenêtre principal :

Private Sub Config_Click()
frmConfig.Show
End Sub

Private Sub Form_Load()
Dim tabPir1(4) As String
Dim tabPir2(4) As String
Dim tabPeri1(4) As String
Dim tabPeri2(4) As String
Dim i As Integer

tabPeri1(0) = "0C10"
tabPeri1(1) = "4C50"
tabPeri1(2) = "8C90"
tabPeri1(3) = "1C00"
tabPeri2(0) = "0CF0"
tabPeri2(1) = "4CB0"
tabPeri2(2) = "8C70"
tabPeri2(3) = "1CE0"
tabPir1(0) = "1450"
tabPir1(1) = "4400"
tabPir1(2) = "84C0"
tabPir1(3) = "1450"
tabPir2(0) = "14D0"
tabPir2(1) = "4480"
tabPir2(2) = "8440"
tabPir2(3) = "14D0"

End Sub


Private Sub Socket_Connect() 'On vient de se connecter (on le dit)
Picture1(1).Picture = LoadPicture("C:\LED\green.JPG")
End Sub

Private Sub Socket_DataArrival(ByVal bytesTotal As Long) 'Les données arrivent
Dim strdata As String
Dim data As Long
txtResult.Text " data " & Hex(data)
End Sub 



Le problème est que je ne reçoit pas les paquets de données en entier et pas dans le bon ordre voulus !
Si je ne fait pas la conversions en Hex , je reçoit des caractères ilisibles, comment doit je faire pour recevoir sur ma socket client les données dans le bon ordres et en entier ?
Merci pour vos réponses !

______________________________________________________________
Kamel Bouhara
Stagiaire : ESECO SYSTEMS
Web3.0 and Web4.0 appliances for videosurveillance, security and risk protection
http://www.eseco.fr

5 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
81
Salut
Pour les Sockets, il serait sage de charger quelques codes source qui parlent de Chat avec socket pour découvrir les subtilités de ce composant.

Tu y découvriras, par exemple, que le déclenchement de DataArrival ne veut pas dire que toutes les données sont arrivées, mais simplement qu'il y a quelque chose à lire dans le buffer.
Il te faut donc gérer la mémorisation des données jusqu'à ce qu'elles soient complètes.
Pour être complètes, il faut le savoir, le socket ne te le dira pas.
Il faut donc imaginer un protocole simple permettant au récepteur de savoir quand commence et quand fini une transmission.
Par exemple, en envoyant "::DEBUT::" avant les données et "::FIN::" après.
A toi, côté réception de détecter ces textes particuliers. Tout ce qui se trouvera au milieu seront tes vraies données.

Dans DataArrivals, il serait bon de lire les données du socket, ça peut servir !!
Socket.GetData ...
Tu ne pourras pas lire les données avec un Long puisque la taille des données peut être beaucoup plus grande.
Vois l'utilisation des tableaux de Bytes ou des String

D'autre part, revois l'utilisation de Hex(data).
Si tu veux voir une série de Bytes, il te faut faire des découpages.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
29
Date d'inscription
lundi 11 janvier 2010
Statut
Membre
Dernière intervention
19 septembre 2010

Tu y découvriras, par exemple, que le déclenchement de DataArrival ne veut pas dire que toutes les données sont arrivées, mais simplement qu'il y a quelque chose à lire dans le buffer.
Il te faut donc gérer la mémorisation des données jusqu'à ce qu'elles soient complètes.


Salut, Jack !

Je pensait que la fonction DataArrival m'aurait renvoyer toute les données, et en effet ce n'est pas trop le cas ...
Je vais donc me documenter sur la gestion des sockets avec Winsock (ou dll) pour savoir si il n'y a pas une fonction qui gére le buffer et m'inspirer ainsi du code que j'avais déja écris en C et que voici :
#if defined (WIN32)
#include <winsock2.h>
#elif defined (linux)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include 
#include 
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close (s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif
#include <stdio.h>
#include <stdlib.h>


int finish;
char mot;
int sock_err;

int main (void)
{
    #if defined (WIN32)
        WSADATA WSAData;
        int erreur = WSAStartup(MAKEWORD(2,0), &WSAData);
    #else
        int erreur = 0;
    #endif
    SOCKET sock;
    SOCKADDR_IN sin;
    SOCKET csock;
    SOCKADDR_IN csin;
    int recsize = (int) sizeof csin;
    unsigned char buffer[512]="";
unsigned char mat[]={0,0,0};
unsigned char state[]={0,0};
int Nbr;
int i;
unsigned char cmdVisonic[]={0xF0,0x40};


    // Si les sockets Windows fonctionnent
    if(!erreur)
    {
        // Création de la socket
        sock = socket(AF_INET, SOCK_STREAM, 0);
        // Configuration de la connexion
        sin.sin_addr.s_addr = inet_addr("192.168.1.245");
        sin.sin_family = AF_INET;
        sin.sin_port = htons(10001);
         sock_err = bind (sock, (SOCKADDR *) &sin, sizeof sin);
        // Si l'on a réussi à se connecter
        finish =1;
              
 
        //csock = accept (sock, (SOCKADDR *) &csin, &recsize);
        
     
        if(connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != SOCKET_ERROR)
        {
            printf("Connection à %s sur le port %d\n", inet_ntoa (sin.sin_addr), htons(sin.sin_port));
            
            // Si l'on reçoit des informations : on les affiche à l'écran
        
             if ((Nbr=send(sock, cmdVisonic, 2,0))!=SOCKET_ERROR)  {
 printf("Sent Visonic command\n");

                 do
                 {
                   if((Nbr=recv(sock, buffer, sizeof(buffer), 0)) != SOCKET_ERROR) {
//                     printf("Recu : Nbr - %d\n", Nbr);

 if (Nbr==1) {
 switch (buffer[0]){
 case 0x24:
//	 printf("PIR detector\n");
 break;
 case 0x42:
//	 printf("telecommande\n");
 break;
                         }
 }
 else {
    if (Nbr==5) {
//									printf("TCode materiel PIR : %02x%02x%02x  - etat :%02x%02x  %02x%02x\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],state[0],state[1]);
if ((buffer[0]==mat[0]) && (buffer[1]==mat[1]) && (buffer[2]==mat[2])) {
//								printf("Here\n");
if (!((buffer[3]==state[0]) && (buffer[4]==state[1]))) {
printf("Code materiel PIR : %02x%02x%02x  - etat :%02x%02x\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
state[0]=buffer[3];
state[1]=buffer[4];
    }
}
else {
mat[0]=buffer[0];
mat[1]=buffer[1];
mat[2]=buffer[2];
state[0]=buffer[3];
state[1]=buffer[4];
printf("Code materiel PIR : %02x%02x%02x  - etat :%02x%02x\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
}
                        }
    if (Nbr==9) {
if ((buffer[4]==mat[0]) && (buffer[5]==mat[1]) && (buffer[6]==mat[2])) {
if (!((buffer[7]==state[0]) && (buffer[8]==state[1]))) {
printf("Code materiel telecommande: %02x%02x%02x  - etat :%02x%02x\n",buffer[4],buffer[5],buffer[6],buffer[7],buffer[8]);
state[0]=buffer[7];
state[1]=buffer[8];
    }
}
else {
mat[0]=buffer[4];
mat[1]=buffer[5];
mat[2]=buffer[6];
state[0]=buffer[7];
state[1]=buffer[8];
printf("Code materiel telecommande: %02x%02x%02x  - etat :%02x%02x\n",buffer[4],buffer[5],buffer[6],buffer[7],buffer[8]);
}
                        }
     }
         //   for (i=0;i<Nbr; i++)
       //    printf("%02x ",buffer[i]);
                     //}
/*            
                 if (buffer[0]=='1')
                   {
                     //sock_err = listen (sock, 5);
                     puts("Saisir une lettre")      ;    
                     scanf("%s", &buffer);
                      sock_err = send(csock, buffer, sizeof(buffer), 0);
                    
                        if (sock_err != SOCKET_ERROR)
                        printf("Chaine envoyée : %s\n", buffer);
                        else puts("error");
                 }
                 else
                     puts("Oh no!");
*/
   }

                 }
                 while (finish == 1);
  }
  else
  printf("Failed sending command\n");
        }
       
        
        
        // sinon, on affiche "Impossible de se connecter"
        else
            printf("Impossible de se connecter\n");
        //finish++;
        
        // On ferme la socket
        closesocket(sock);
        #if defined (WIN32)
            WSACleanup();
        #endif
    }
    // On attend que l'utilisateur tape sur une touche, puis on ferme
    getchar();
    return EXIT_SUCCESS;
}


Encore faut-il que je puisse faire la même chose sous VB ( ce qui devrais être le cas :) ) !
Merci Jack de m'avoir un peu plus éclairer .
Messages postés
29
Date d'inscription
lundi 11 janvier 2010
Statut
Membre
Dernière intervention
19 septembre 2010

Salut,

Finalement la solution à mon poblème s'avèrait être assez simple (j'avais de mauvaises références au départ )

Et j'arrive à recevoir tout mes octets, dans mon code VB précédent je cherchais à recevoir des String:
Private Sub Socket_DataArrival(ByVal bytesTotal As Long) 'Les données arrivent
Dim strdata As String
Dim data As Long
txtResult.Text " data " & Hex(data)
End Sub 


Voila donc mon code pour recevoir mes bon octets avec ma socket client :
Private Sub Socket_DataArrival(ByVal bytesTotal As Long) 'Les données arrivent
Dim strdata As String
Dim data As Byte
ESECO.txtData ESECO.txtData & "longueur " & CStr(bytesTotal) & vbCrLf
For i = 1 To bytesTotal
   socket.GetData data, vbByte
   ESECO.txtData = ESECO.txtData & Hex(data) & " "
Next
ESECO.txtData = ESECO.txtData & vbCrLf & vbCrLf


A+
_______________________________________________
Kamel Bouhara
ESECO SYSTEMS
http://www.eseco.fr
Web3.0 and Web4.0 appliances for security and risk protection
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
81
Ok
Tu peux aussi lire tout sans faire de boucle :
(Evite d'utiliser des mots pouvant ressembler à un objet ou mo clé du système, comme data)
   Dim aData() As Byte
   ReDim aData(0 To bytesTotal - 1)
   socket.GetData aData(0), vbByte, bytesTotal
ou qqchose de ressemblant

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
29
Date d'inscription
lundi 11 janvier 2010
Statut
Membre
Dernière intervention
19 septembre 2010

Salut ! Merci du conseil jack , et pour ton alternative , elle me semble bonne aussi, je vais la tester .

a+
_________________________________________________
Kamel Bouhara
ESECO SYSTEMS
http://www.eseco.fr
Web3.0 and Web4.0 appliances for security and risk protection