Sockets en C++?

Sockets en C++? - C++ - Programmation

Marsh Posté le 20-01-2003 à 08:08:01    

salut,
Je cherche une API pour prendre le controle d'une application Telnet.
 
(sauvegarde de config sw Cisco)
 
et une autre pour accéder au réseau :/
 
merci :/


Message édité par AGA le 20-01-2003 à 15:37:27
Reply

Marsh Posté le 20-01-2003 à 08:08:01   

Reply

Marsh Posté le 20-01-2003 à 11:36:13    

Tu veux acceder à une appli telnet en C ? Corrigez moi si je me trompe mais le plus simple est de voir du coté des WinSocks.


Message édité par Kristoph le 20-01-2003 à 12:10:11
Reply

Marsh Posté le 20-01-2003 à 11:58:48    

je veux automatiser une procédure que l'on fait manuellement avec un telnet.
 
Cad :
 telnet @ip
envoye d'une commande
envoye d'une autre commande
ferme le telnet
 
voilà

Reply

Marsh Posté le 20-01-2003 à 12:10:57    

Utilise WinSocks et recode à la main le protocole Telnet. Cherche sur google et tu veras que c'est pas trop difficile :D

Reply

Marsh Posté le 20-01-2003 à 15:08:30    

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib" )
 
void main()
{
 WSADATA WSAData;
 WSAStartup(MAKEWORD(2,0), &WSAData); /* On va utiliser des sockets */
 
 SOCKET sock;
 SOCKET csock;
 SOCKADDR_IN sin;
 SOCKADDR_IN csin;
 char *buffer = new char[255];
 
 
 
 /* *****************
 Définition du socket
 ***************** */
 sock = socket(AF_INET, SOCK_STREAM, 0);
 
 sin.sin_addr.s_addr   = inet_addr("175.16.250.24" ); /* IP de mon Switch */
 sin.sin_family    = AF_INET;
 sin.sin_port    = htons(23); /* numéro du port */
 
 /* *****************
 Utilisation du socket
 ***************** */
 connect(sock, (SOCKADDR *)&sin, sizeof(sin)); /* Appli client, on se connecte... */
 
 recv(sock, buffer, sizeof(buffer), 0); /* On reçoie l'info */
 
 
 
    printf("Début\r\n" ); // afficher à l'écran
 
    send(csock, "pass\r\n", 10, 0);
    send(csock, "enable\r\n", 10, 0);
    send(csock, "pass\r\n", 10, 0);
    send(csock, "copy run tftp\r\n", 17, 0);
    send(csock, "175.16.1.213\r\n", 16, 0);
    send(csock, "nomcfg\r\n", 7, 0);
    send(csock, "quit\r\n", 8, 0);
 
    printf("C pas gagné" ); // afficher à l'écran
 
 
 /* *****************
 Fermeture du socket
 ***************** */
 closesocket(sock);
 WSACleanup();
 
}


 
je fais ça, mais ça marche pas,
je vois pas comment tester ce que je fait :/

Reply

Marsh Posté le 20-01-2003 à 15:18:25    

j'ai essayé un truc
un serveur


#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib" )
 
void main()
{
 WSADATA WSAData;
 WSAStartup(MAKEWORD(2,0), &WSAData); /* On va utiliser des sockets */
 
 SOCKET sock;
 SOCKET csock;
 SOCKADDR_IN sin;
 SOCKADDR_IN csin;
 
 sock = socket(AF_INET, SOCK_STREAM, 0);
 
 sin.sin_addr.s_addr   = INADDR_ANY;
 sin.sin_family    = AF_INET;
 sin.sin_port    = htons(23); /* numéro du port */
 
 bind(sock, (SOCKADDR *)&sin, sizeof(sin));
 listen(sock, 0); /* Initialisation du socket */
 
 while(1)
 {
  int sinsize = sizeof(csin);
  if((csock = accept(sock, (SOCKADDR *)&csin, &sinsize)) != INVALID_SOCKET)
  {
   send(csock, "Hello world!\r\n", 14, 0);
  }
 }
}


Code :
  1. #include <stdio.h>
  2. #include <winsock2.h>
  3. #pragma comment(lib, "ws2_32.lib" )
  4. void main()
  5. {
  6. WSADATA WSAData;
  7. WSAStartup(MAKEWORD(2,0), &WSAData); /* On va utiliser des sockets */
  8. SOCKET sock;
  9. SOCKET csock;
  10. SOCKADDR_IN sin;
  11. SOCKADDR_IN csin;
  12. char *buffer = new char[255];
  13. /* *****************
  14. Définition du socket
  15. ***************** */
  16. sock = socket(AF_INET, SOCK_STREAM, 0);
  17. sin.sin_addr.s_addr   = inet_addr("127.0.0.1" ); /* IP de mon Switch */
  18. sin.sin_family    = AF_INET;
  19. sin.sin_port    = htons(23); /* numéro du port */
  20. /* *****************
  21. Utilisation du socket
  22. ***************** */
  23. connect(sock, (SOCKADDR *)&sin, sizeof(sin)); /* Appli client, on se connecte... */
  24.     recv(sock, buffer, sizeof(buffer), 0); /* On reçoie l'info */
  25.     printf(buffer); // afficher à l'écran
  26. /* *****************
  27. Fermeture du socket
  28. ***************** */
  29. closesocket(sock);
  30. WSACleanup();
  31. }


un client
 
j'affiche le resultat du serveur, effectivement ça marche mais y a plein de caractère transformé :??:
 
bon bettement j'affiche le buffer
(je suis newbie en C++ moi :o)

Reply

Marsh Posté le 20-01-2003 à 19:24:58    

ça marche un peu,
mais le buffer j'ai un peu de mal :o
 
il etait trop petit, mais entre chaque appel il reste l'ancien buffer
 
enfin jsais aps trop  :??:

Reply

Marsh Posté le 20-01-2003 à 19:31:26    

Fais gaffe, recv te renvoye le nombre d'octets lus. Si tu n'en tiens pas compte, c'est sur qu'il te restera des bouts de l'ancien message. Je rappelle que les sockets, c'est de la communication binaire, donc les données ne sont pas de chaines C normalles ( celles avec un '\0' au bout )

Reply

Marsh Posté le 20-01-2003 à 19:37:27    

Cad, tu peux preciser un tout petit peu plus,
je sais que ça doit être evident mais je n'ai jamais codé en C :/
 
 :jap:

Reply

Marsh Posté le 20-01-2003 à 20:25:26    

Se lancer comme ça dans le C en faisant une appli reseau c'est pas forcement l'idéal pour débuté :)
 
Si le but est d'apprendre le C, commence par quelque chose de plus simple. Si le but est vraiment de faire cette appli, essaye un autre langage plus adapté comme le Python par exemple =>
 
http://python.org/
http://www.python.org/doc/2.2.2/li [...] etlib.html

Reply

Marsh Posté le 20-01-2003 à 20:25:26   

Reply

Marsh Posté le 20-01-2003 à 20:30:34    

le but est de faire cette appli
 
elle est pas compliqué, une fois reglé les pb de buffer et d'affichage
 
C bon
 
si tu veux bien juste donner un chouia d'explication sur ce buffer ce serait super
 
merci ;)

Reply

Marsh Posté le 20-01-2003 à 21:17:44    

Comme tu veux ...
 
Alors en C, une chaine de caractères se représente par une suite de "char" ( un tableau de char ) et qui se termine par le char '\0'. Toi, tu reçois une suite de char sans le '\0' terminal, mais en échange tu as la taille du tableau.
 
Ce que tu dois faire c'est :
- prévoir un tampon assez grand pour contenir le resultat de recv + 1 caractère
- écrire un '\0' juste après le dernier caractère reçu.
 

Code :
  1. const int MAX_BUFFER = 256;
  2. char *buffer = new char[MAX_BUFFER+1];
  3. //.....( du code ).....
  4. int len = recv(sock, buffer, MAX_BUFFER, 0);
  5. buffer[len] = '\0';
  6. // maintenant, cette commande :
  7. printf(buffer);
  8. // car buffer contient une chaine C valide


 
Et pour finir, je ne comprends pas très bien ton problème de caractère transformés, mais c'est peut-être un problème d'encodage. Je te conseilles de te restreindre au caractères ASCII 7 bits et de faire attention à ne pas utiliser de l'Unicode.


Message édité par Kristoph le 20-01-2003 à 21:31:33
Reply

Marsh Posté le 21-01-2003 à 07:59:44    

yes!
 
t'es un  chef.
 
Pour la chaine c la fameuse "chaine à Zero terminal"?
 
Bon pour les caractères bizarres ils apparaissent au premier appel de Recv, je penses que les commandes sont envoyés trop vite.
 
J'ai vu une histoire avec un select, je vais creuser ça, à moins qu'un pause ou wait (ça doit exister :o) suffise.
 
 
Merci  :jap:

Reply

Marsh Posté le 21-01-2003 à 08:26:17    

zut :/
 
ça ce passe bien, puis apres il double la première lettre de la chaine envoyé  :heink:  
alors pour les commandes c pas grave j'ai escapé avec un espace,
mais pour le pass :/

Reply

Marsh Posté le 21-01-2003 à 17:05:05    

:(

Reply

Marsh Posté le 21-01-2003 à 17:14:28    

C'est quoi le problème au juste ?

Reply

Marsh Posté le 21-01-2003 à 18:28:41    

franchement je comprends pas :/
 
Bon je suis bien en TCP ( et non en UDP)
 
le premier recv ne marche pas, enfin a l'affichage c des signe tout gentils (smilies, coeur etc...)
 
le deuxieme fonctionne bien , puisqu'il affiche la demande de mdp du switch
 
le premier send fonctionne egalement, je lui envoie le MDP
 
le recv suivant egalement, il affiche bien "l'entete" comme koi je suis loggé
 
(entre chaque send ou recv j'ai mis un Sleep(300);)
 
par contre le send suivant ne marche pas dans le sens ou il envoie bien ma chaine ma en DOUBLANT le premier car
cad j'envoie "enable\r\n"
 
je demande le resultat j'obtiens :
l'entete du switch (normal) la commande (enable) mais doublé càd
eenable, plus le msg d'erreur du switch (bha oui eenable spa pareil que enable :D)
 
bon là a la limite on peut ruser, j'envoie " enable" et ça marche car comme il double l'espace, ni vu ni connu
 
ensuite je suis bloqué car le send ne marche pas mieux et pour le pass pas de double espace possible :/
 
en gros le recv semble fonctionner mais le send ne marche proprement qu'une seule fois.
 
Voilà :/
 
j'ai pataugé toute la journée, par tout on lis "recv send" facile pas de pb , bah moi zob :/


Message édité par AGA le 21-01-2003 à 18:30:29
Reply

Marsh Posté le 22-01-2003 à 21:06:15    

Up ça marche un peu mieux en envoyant  
 
"\nenable"
 
mais c qd même pas au point
 
qq'un a une idée?
 
merci

Reply

Marsh Posté le 22-01-2003 à 21:18:36    

C'est probablement parceque telnet est un tout petit peu plus compliqué que d'utiliser des sockets simples. En particulier, tous les caractères entre 128 et 255 servent au protocole de communicatoin entre le client et le serbeur. Les caractères bizarres que tu vois au debut, c'est le serveur telnet qui essaye de parler avec ton programme :)
 
Par exemple, une fin de ligne se marque avec la suite de 2 caractères 0x13 puis 0x10. Je ne pense pas que tu puisses les inverser.


Message édité par Kristoph le 22-01-2003 à 21:19:28
Reply

Marsh Posté le 22-01-2003 à 21:21:06    

:sweat:  
 
le serveur c un switch cisco
 
là en l'etat j'arrive à me logguer
a indiquer la commande pour avoir les privilèges admin
mais ça capote au niveau du pass.
 
si je passe ça il me restera a envoyé encore deux lignes  :sweat:  
 
la finalité c juste faire un copy run tftp!
 
c pas plus dure
 
help :sweat:

Reply

Marsh Posté le 22-01-2003 à 21:22:50    

Kristoph a écrit :


 
Par exemple, une fin de ligne se marque avec la suite de 2 caractères 0x13 puis 0x10. Je ne pense pas que tu puisses les inverser.


 
oui, mais ça ne correspond pas à \r\n?
 
 
c'est dommage jsuis sur que en deux minutes tu trouverait  :sweat:

Reply

Marsh Posté le 23-01-2003 à 00:30:12    

C'est \r\n ou \n\r ?
 
Le mieux pour toi je pense, c'es d'utiliser un telnet normal, mais en même temps de faire un dump de la connection reseau avec un autre programme. Comme ca tu pourras voir exactement ce qui se passe et le reproduire facilement avec ton programme C. ( version "hacker" )
 
La version ingenieur consiste à aller se plonger dans la RFC de telnet mais bon, faut du courage pour faire ce truc.

Reply

Marsh Posté le 24-04-2008 à 16:58:06    

je fais "remonter" ce topic des profondeurs parce que j'ai un prob +/- similaire, j'ai besoin d'enchainer les recv() et send(), seulement seul les premiers appels fonctionnent, je suis obligé a chaque fois de me reconnecter. C'est normal ou il y a un moyen d'eviter cela ? Je n'ai pas trouvé beaucoup de doc sur les socket, et c'est tjs la meme ( tuto recopiés d'un site a l'autre .. )

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed