[résolu] C++ et les horribles \0\0
Dernière réponse : dans Programmation
Bonjour,
J'ai ecrit un programme serveur en C++ ( sous Dev Cpp ) et un programme client en VB 6.0. Ils marchent ( sisi ) mais il y a un probleme, car quand VB envoie une chaine avec :
le serveur recoit :
Or dans mon code en C++ il est ecrit :
donc buffer!=1
Comment puis j'enlever ces horribles zeros ???
J'ai ecrit un programme serveur en C++ ( sous Dev Cpp ) et un programme client en VB 6.0. Ils marchent ( sisi ) mais il y a un probleme, car quand VB envoie une chaine avec :
frmClient.Socket.SendData 1
le serveur recoit :
1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0...
Or dans mon code en C++ il est ecrit :
if(buffer=="1")
{
send(sock,"reponse",sizeof("reponse"),0);
}
donc buffer!=1
Comment puis j'enlever ces horribles zeros ???
Autres pages sur : resolu horribles
Lassé par la pub ? Créez un compte
si "buffer" est de type char *, ton test ne fait qu'une comparaison de pointeur (qui sont forcément toujours différents). En utilisant le strcmp, ça compare jusqu'au \0:
Et pense au '\0' pour les tailles des paquets envoyés.
if( strcmp(buffer, "1") == 0 )
{
send(sock,"reponse",sizeof("reponse" ),0);
}
Et pense au '\0' pour les tailles des paquets envoyés.
Non j'ai ecrit cette fonction pour traiter les données rentrantes il pour un autre de mes programmes qui est un client et un serveur VB :
Comme ca quel que soit la taille des packets recus on a commeme un fichier compet a la fin.
Et coté serveur c'set tout bete :
Mais esque en C++ le coté serveur sera pareil ??? ( ca marrangerait xD )
Sub IncomingData(ByVal DataLength As Long)
Dim buffer() As Byte
Dim data As String
Dim parse() As String
On Error Resume Next
If ok = False Then ' est ce une demande ou un fichier qui arrive ?
DAFORM.Socket.GetData data, vbString, DataLength
parse = Split(data, SEP_CHAR)
parse(0) = LCase(parse(0))
If parse(0) = "file" Then
If parse(1) = "" Then Exit Sub
FileName = DAFORM.txtPath.Text & "\" & parse(1)
DaFile = parse(1)
Open FileName For Binary As #2
DAFORM.ProgressBar1.Max = parse(2)
ok = True
Else
DAFORM.Command1.Enabled = True
End If
Else 'si c'est le fichier qui arrive
DAFORM.Socket.GetData buffer
Put #2, pos, buffer
DAFORM.lblConnection.Caption = "Telechargement en cours ! " & Int((DAFORM.ProgressBar1.Value / DAFORM.ProgressBar1.Max) * 100) & " % recus."
pos = pos + UBound(buffer) + 1
DAFORM.ProgressBar1.Value = DAFORM.ProgressBar1.Value + DataLength
If DAFORM.ProgressBar1.Value = DAFORM.ProgressBar1.Max Then Close #2: DAFORM.lblConnection.Caption = "Telechargement terminé !": ok = False: pos = 1: DAFORM.Command1.Enabled = True: DAFORM.Command2.Enabled = False: MsgBox "Le fichiera bien été mis a jour !": Shell DaFile: End
End If
End Sub
Comme ca quel que soit la taille des packets recus on a commeme un fichier compet a la fin.
Et coté serveur c'set tout bete :
frmServer.Socket(index).SendData Buffer
DoEvents
Mais esque en C++ le coté serveur sera pareil ??? ( ca marrangerait xD )
Les Socket fonctionnent au niveau de l'OS, donc le fonctionnement est le même quel que soit le langage.
Peut-être qu'en VB il y a une surcouche, mais je ne crois pas. Je pense que le comportement en C++ est le même.
Dans ton exemple 100% VB, tu n'as pas de problème si tu envoies un fichier qui dépasse les 64ko ?
Peut-être qu'en VB il y a une surcouche, mais je ne crois pas. Je pense que le comportement en C++ est le même.
Dans ton exemple 100% VB, tu n'as pas de problème si tu envoies un fichier qui dépasse les 64ko ?
Je continue le post :
Donc j'ai un probleme c'est que mon programme serveur n'arrive pas a detecter que le client s'est deconnecté, donc le socket n'est plus en ecoute et au bout de deux connexion a mon programme serveur celui ci se bloque, voici le code
Ce code est basé sur l'exemple du site du zero.
EDIT:
En faite ce que je voudrais c'est que le serveur ferme le socket a la perte de connexion avec le client ( coupure d'internet ) et qu'il reouvre immediatement le socket pour que le client puisse se reconnecter mais au bout de deux connection le serveur bug et reponds plus
A mon humble avis c'est sock_err = listen (csock, 5); qui ne va pas, mais je ne sais pas comment le remplacer pour verifier si le client est toujours connecté !
Ps: Vive le VB franchement !
If Socket.State <> sckConnected Then
MsgBox "Client deconnecté !", vbInformation, "Erreur !"
End If
Et voilaaaaaaaaaaa, et en C/C++ il faut chercher dans une disaine de manuels pour trouver son bonheur xD
Donc j'ai un probleme c'est que mon programme serveur n'arrive pas a detecter que le client s'est deconnecté, donc le socket n'est plus en ecoute et au bout de deux connexion a mon programme serveur celui ci se bloque, voici le code
// Si les sockets Windows fonctionnent
if(!erreur)
{
sock = socket (AF_INET, SOCK_STREAM, 0);
// Si la socket est valide
if (sock != INVALID_SOCKET)
{
printf ("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
sin.sin_addr.s_addr = htonl (INADDR_ANY); // Adresse IP automatique
sin.sin_family = AF_INET; // protocole familial (IP)
sin.sin_port = htons (7777); // listage du port
while(1)
{
//sock_err = bind (sock, (SOCKADDR *) &sin, sizeof sin);
sock_err = listen (csock, 5);
//Si la socket fonctionne
if (sock_err != SOCKET_ERROR)
{
// démarrage du listage (mode server)
sock_err = listen (sock, 5);
printf ("Listage du port %d...\n", 7777);
//Si la socket fonctionne
if (sock_err != SOCKET_ERROR)
{
// Attente pendant laquelle le client se connecte
printf ("Ecoute sur le port 7777...\n");
csin.sin_addr.s_addr = htonl(7777);
csin.sin_family = AF_INET;
csin.sin_port = htons(7777);
if((csock = accept (sock, (SOCKADDR *) &csin, &recsize))!=INVALID_SOCKET)
{
printf ("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa (csin.sin_addr), htons (csin.sin_port));
sock_err = send(csock, buffer, sizeof(buffer), 0);
while(sock_err != SOCKET_ERROR)
{
sock_err = listen (csock, 5);
if (sock_err==0)
{
csock = accept (sock, (SOCKADDR *) &csin, &recsize)!=INVALID_SOCKET ;
}
memset(buffer,0,sizeof(buffer));
recv(csock,buffer,sizeof(buffer),0);
printf("%s",buffer);
if(strcmp(buffer,"1")==0)
{
send(csock, buffer, sizeof(buffer), 0);
}
}
}
else
{
printf("Socket fermé.\n");
shutdown (csock, 2);
}
}
//Il ne faut pas oublier de rompre la connexion (fermée dans les deux sens)
}
}
// fermeture de la socket
printf ("Fermeture de la socket...\n");
sock_err = closesocket(sock);
printf ("Fermeture du serveur terminee\n");
}
Ce code est basé sur l'exemple du site du zero.
EDIT:
En faite ce que je voudrais c'est que le serveur ferme le socket a la perte de connexion avec le client ( coupure d'internet ) et qu'il reouvre immediatement le socket pour que le client puisse se reconnecter mais au bout de deux connection le serveur bug et reponds plus
A mon humble avis c'est sock_err = listen (csock, 5); qui ne va pas, mais je ne sais pas comment le remplacer pour verifier si le client est toujours connecté !
Ps: Vive le VB franchement !
If Socket.State <> sckConnected Then
MsgBox "Client deconnecté !", vbInformation, "Erreur !"
End If
Et voilaaaaaaaaaaa, et en C/C++ il faut chercher dans une disaine de manuels pour trouver son bonheur xD
Il faut tester le retour de "recv":
- Si >0, c'est le nombre d'octets reçus
- Si ==0, la connexion est coupée
- Si <0, il y a une erreur socket
Même chose sur le "send"
Les listen et accept, c'est juste pour établir une connexion. Le accept est bloquant jusqu'à ce qu'un client se connecte sur le port écouté. A ce niveau, rien n'est connecté.
C'est send et recv qui font la communication, c'est donc sur eux qu'il faut tester si la communication est toujours présente. Le recv est bloquant en lecture, mais peut être débloqué si une erreur de connexion ou une perte de connexion se produit.
En VB c'est simple, mais en fait plus complexe parce que c'est une surcouche des sockets
- Si >0, c'est le nombre d'octets reçus
- Si ==0, la connexion est coupée
- Si <0, il y a une erreur socket
Même chose sur le "send"
Les listen et accept, c'est juste pour établir une connexion. Le accept est bloquant jusqu'à ce qu'un client se connecte sur le port écouté. A ce niveau, rien n'est connecté.
C'est send et recv qui font la communication, c'est donc sur eux qu'il faut tester si la communication est toujours présente. Le recv est bloquant en lecture, mais peut être débloqué si une erreur de connexion ou une perte de connexion se produit.
En VB c'est simple, mais en fait plus complexe parce que c'est une surcouche des sockets
Lassé par la pub ? Créez un compte
- Contenus similaires :
Tags :
- ForumProgrammation client serveur sous windows
- solutionsComment programmer en flash
- ForumBases de la programmation
- ForumProgramme java client-serveur sockets
- ForumProgramme pour changer adresse ip
- ForumUn programme qui ameliore le ping
- ForumProgramme comme emule
- ForumPhp connexion a un serveur ftp
- ForumComment programme un serveur dns et dhcp
- ForumDialogue entre un serveur et un client
- Voir plus