[C++]send() entre win et linux
lucichose
Messages postés
39
Date d'inscription
Statut
Membre
Dernière intervention
-
Char Snipeur Messages postés 9813 Date d'inscription Statut Contributeur Dernière intervention -
Char Snipeur Messages postés 9813 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour,
Je rencontre une problème assez particulier entre mon windows et mon linux.
Mon module réseau fonctionne parfaitement au niveau de la connexion des pc entre eux et la detection de l'un et de l'autres cependant une fois la connexion établie je fait des tests d'envois de paquets et la le problème survient.
Si j'envois un paquet de linux a windows , le pc windows le recois sans problème, mais si je fait l'envois de paquet de windows vers linux à ce moment la le send () ( ou sendto () ) ne fonctionne pas. Le pc linux ne le reçoit jamais et la méthode d'envois me retourne une erreur qui une fois log est : "no such file or directory" .
Les envois de linux vers windows et windows vers linux s'effectuent de la même maniere. J'ai verifier mon socket l'adresse du destinataire , le contenu du message et tout est convenable. Si j'utilise cela entre deux windows cela fonctionne à merveille.
Quelle subtilité de linux aurais je homis pour que cela ne soit pas reçu lorsque j'envois des paquets de win vers linux?
Y aurait t'il des choses spéciales pour les sockets sur linux, ou les ports ( j'ai essayer les ports : 27050 / 32000 / 40000 )?
Merci d'avance de votre aide ou de vos suggestions.
Cordiallement
PS : Les sockets sont à ce moment en TCP.
Je rencontre une problème assez particulier entre mon windows et mon linux.
Mon module réseau fonctionne parfaitement au niveau de la connexion des pc entre eux et la detection de l'un et de l'autres cependant une fois la connexion établie je fait des tests d'envois de paquets et la le problème survient.
Si j'envois un paquet de linux a windows , le pc windows le recois sans problème, mais si je fait l'envois de paquet de windows vers linux à ce moment la le send () ( ou sendto () ) ne fonctionne pas. Le pc linux ne le reçoit jamais et la méthode d'envois me retourne une erreur qui une fois log est : "no such file or directory" .
Les envois de linux vers windows et windows vers linux s'effectuent de la même maniere. J'ai verifier mon socket l'adresse du destinataire , le contenu du message et tout est convenable. Si j'utilise cela entre deux windows cela fonctionne à merveille.
Quelle subtilité de linux aurais je homis pour que cela ne soit pas reçu lorsque j'envois des paquets de win vers linux?
Y aurait t'il des choses spéciales pour les sockets sur linux, ou les ports ( j'ai essayer les ports : 27050 / 32000 / 40000 )?
Merci d'avance de votre aide ou de vos suggestions.
Cordiallement
PS : Les sockets sont à ce moment en TCP.
A voir également:
- [C++]send() entre win et linux
- Local send - Télécharger - Divers Utilitaires
- Win rar - Télécharger - Compression & Décompression
- Linux reader - Télécharger - Stockage
- Win dir stat - Télécharger - Gestion de fichiers
- Win setup from usb - Télécharger - Utilitaires
6 réponses
as tu essayé de Linux à Linux ?
une histoire de parefeu ?
peut être une taille de donnée qui n'est pas la même des deux cotés (sizeof(long) par exemple).
3 chose à vérifier(dans le désordre).
Bonne chance.
une histoire de parefeu ?
peut être une taille de donnée qui n'est pas la même des deux cotés (sizeof(long) par exemple).
3 chose à vérifier(dans le désordre).
Bonne chance.
alors pour la taille des données c'est bien les mêmes, de linux a linux cela ne fonctionne pas hormis si je me connecte directement sur l'adresse mais les send de broadcast ne passe pas.
les send de broadcast ne passe pas.
Voilà qui est un peu plus précis et pourrait être la source du problème.
Déjà, le broadcast en mode connecté (tcp) je ne suis pas sur que ça ait un sens, mieux vaut de l'UDP.
Il est possible que sous Linux les messages broadcast soient filtrés... il faut se renseigner.
Voilà qui est un peu plus précis et pourrait être la source du problème.
Déjà, le broadcast en mode connecté (tcp) je ne suis pas sur que ça ait un sens, mieux vaut de l'UDP.
Il est possible que sous Linux les messages broadcast soient filtrés... il faut se renseigner.
non les broadcast, bien sur je les faient en UDP. quant je disaient qu'ils ne passaient pas c'etaient entre 2 linux. cependant win -> linux et linux-> win sa passe
dans ce bout de code le pc est serveur il attend un message et si il en recois un il repond a son tour ( MODE TCP)
ici le pc est Client , une fois la connexion etablie, il envois un message au serveur ( Mode TCP ) :
int SelectServerThread::protectedRun ( ) { while ( !bClose ) { ID_IP.clear ( ); //Verouille le mutex pthread_mutex_unlock ( &myMutex ); //Recuperation des donn?es des utilisateurs connect?s ((ServerMultiThreadLinux*)TheServer)->Get_myID_Ip_User ( ID_IP ); //Lock le mutex pthread_mutex_lock ( &myMutex ); if ( !ID_IP.empty ( ) ) { //Creation d'un iterateur au debut de la map kstl::map < int, CONNEXION* >::iterator It = ID_IP.begin ( ); fd_set Set_Read; fd_set Set_Exept; fd_set Set_Write; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 10000; //Parcour de la map while ( It != ID_IP.end ( ) ) { //Initialisation des valeurs myReader.clear ( ); myWriter.clear ( ); myExept.clear ( ); FD_ZERO ( &Set_Read ); FD_ZERO ( &Set_Exept ); FD_ZERO ( &Set_Write ); FD_SET ( ( *It ).second->Socket, &Set_Read ); FD_SET ( ( *It ).second->Socket, &Set_Write ); FD_SET ( ( *It ).second->Socket, &Set_Exept ); It++; } //Select int iValue = select ( 0, &Set_Read, &Set_Write, &Set_Exept, &tv ); if ( iValue ) { kstl::map < int, CONNEXION* >::iterator It = ID_IP.begin ( ); while ( It != ID_IP.end ( ) ) { if ( FD_ISSET ( ( *It ).second->Socket, &Set_Read ) ) { myReader.push_back ( ( *It ).second->Socket ); } if ( FD_ISSET ( ( *It ).second->Socket, &Set_Write ) ) { myWriter.push_back ( ( *It ).second->Socket ); } if ( FD_ISSET ( ( *It ).second->Socket, &Set_Exept ) ) { myExept.push_back ( ( *It ).second->Socket ); } It ++; } } //Iterateur reader kstl::vector <int>::iterator ItReader = myReader.begin ( ); //Parcour du vecteur while ( ItReader != myReader.end ( ) ) { //erase buffer for ( int i = 0; i < 200; i++ ) { myMessage [i] = 0; } //reception du message int iReceiveLenght = recv ( ( *ItReader ), myMessage, 200, 0 ); if ( iReceiveLenght > 0 ) { printf ( "Paquet recu\n"); //Sauvegarde du message dans le buffer du serveur TheServer->AddMessage ( myMessage, iReceiveLenght ); //Renvoi d'un r?ponse kstl::string Message; Message = "Reponse"; //Recuperation de la taille du message int MessageLenght = Message.size ( ); //envois le message send ( ( *ItReader ), Message.c_str ( ) , MessageLenght, 0 ); } else { printf ( "Paquet non recu\n" ); } //incr?mentation de l'iterateur ItReader++; } } } return 0; }
ici le pc est Client , une fois la connexion etablie, il envois un message au serveur ( Mode TCP ) :
bool ClientMultiThreadLinux::ConnectToAdress ( kstl::string strIP ) { if ( !mybIsConnect ) { //Address de destination struct sockaddr_in DestAddr; DestAddr.sin_family = AF_INET; DestAddr.sin_port = htons ( ulRemotePort ); DestAddr.sin_addr.s_addr = inet_addr( strIP.c_str () ); // z?ro pour le reste de la struct memset ( &DestAddr.sin_zero, 0 , sizeof ( DestAddr.sin_zero ) ); //Initialisation du socket en TCP myConnectedSocket = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); //Connexion au serveur distant int TryToConnect = 0; int iValue = -1; //Fait 10 test de connexion en cas d'echec while ( ( iValue < 0 ) && ( TryToConnect <= 10 ) ) { //Connexion iValue = connect ( myConnectedSocket, ( struct sockaddr * ) &DestAddr, sizeof ( struct sockaddr ) ); if ( iValue >= 0 ) { //Connexion reussi mybIsConnect = true; } TryToConnect ++; } //Connexion echouer if ( iValue < 0 ) { printf ( "Not connection found\n" ); //Fermeture du socket close ( myConnectedSocket ); return false; } //Connexion reussi else { printf ( "Connexion succes\n" ); //Lancement du Thread d'ecoute de message if ( myReceiveClientThread == NULL ) { myReceiveClientThread = ( ReceiveClientThread* ) ( Core::GetInstanceOf ( "myReceiveClientThread", _S_2_ID ( "ReceiveClientThread" ) ) ); myReceiveClientThread->setValue ( "mySocket", myConnectedSocket ); myReceiveClientThread->Init ( ); } while ( 1 ) { kstl::string Message; Message = "test 2.h"; //Recuperation de la taille du message int MessageLenght = Message.size ( ); send ( myConnectedSocket, Message.c_str ( ), MessageLenght, 0 ); sleep ( 5 ); } return true; } } }
je vois que tu envoies des chaines de caractères. Il est possible, dans ce cas, que le problème vienne du recv où tu lui dit 200 en réception.
essai d'envoyer comme chaine de caractère ce que tu veux suivi de \r\n peut être que comme ça recv détectera que la chaine est finie et sortira de la boucle.
essai d'envoyer comme chaine de caractère ce que tu veux suivi de \r\n peut être que comme ça recv détectera que la chaine est finie et sortira de la boucle.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
je vien de tester mais cela ne change rien :(
Cela pourais t'il venir du fait que je n'ai pas de DNS dériere pour effectuer mes test ?
Cela pourais t'il venir du fait que je n'ai pas de DNS dériere pour effectuer mes test ?
En c++, un caractère de fin de chaine n'est pas "\r\n" (qui est le retour a la ligne made in microsoft), mais "\0".
c'est vrai que ce que je dit est ambigüe. De mémoire, il me semble que recv test les chaines de caractères et s'arrête sur les retours à la ligne. Et les retours à la ligne en réseau, c'est \r\n.
\r\n est plus logique que \n seul, car on ne sais pas forcément comment réagit le terminal, \n veux dire "déplacement du curseur sur la ligne suivante", ce qui n'inclu pas forcément de mettre le curseur en début de ligne. Bref...
Par contre, ton histoire de \0 me donne une autre idée.
La taille du message est récupérée avec size(), il doit donc correspondre au nombre de caractères du message. Peut être qu'en mettant "+1" pour envoyer le \0 ça fonctionnerai.
\r\n est plus logique que \n seul, car on ne sais pas forcément comment réagit le terminal, \n veux dire "déplacement du curseur sur la ligne suivante", ce qui n'inclu pas forcément de mettre le curseur en début de ligne. Bref...
Par contre, ton histoire de \0 me donne une autre idée.
La taille du message est récupérée avec size(), il doit donc correspondre au nombre de caractères du message. Peut être qu'en mettant "+1" pour envoyer le \0 ça fonctionnerai.