[C++][Visual 2003] Connection Telnet

Dans le cadre d’un projet je dois envoyer des requêtes en XML via telnet du style:

[code]

|[/code]

Je bosse donc sous Visual C++ .NET 2003 et je voulais savoir quelle était la librairie de sockets ou un truc du style le plus simple à utiliser pour me connecter au serveur et envoyer mes messages et récupérer les réponses.
J’ai l’ip et le port du serveur avec lequel je dois dialoguer.
Si vous savez même quelle sont les fontions à utiliser et comment ca s’utilise je prend aussi.
Je suis méga-noob en C++ et pas bien calé en prog réseau donc je galère un peu mais bon faut bien que je m’y mette la ^^

En C++, j’en ai pas la moindre idée, mais question comme ca, tu peux pas prendre VC# Express et faire tout ca en C# (la gestion reseau a RIEN a voir, ca devient enfantin) ?

Absolument aucune animosité dans ce je vais dire mais:
Vous êtes marrant avec votre C#
Chaque fois que je pose une question sur du C ou du C++, une fois sur deux la réponse c’est « bah pourquoi tu le fais pas en C# » B)
C’est bien gentil mais d’une part je ne connais pas le C# et d’autre part ce que je cherche à faire ici c’est juste un mini programme de test qu’il me faudra ensuite intégrer dans un début de programme existant qui est en C++ (programmation d’un TSP (une DLL en fait) utilisant la librairie TSP++ de Julmar).

J’ai rien contre le C# je ne connais absolument pas mais je pense pas avoir trop le temps d’apprendre un nouveau langage surtout s’l fauten plus que je recode tout derrière. Deja que la prog ca me gonfle…

Mais merci du conseil B)

Ok !
Je demandais juste si tu avais des contraintes vis a vis du C++, si oui, tant pis, en C# je t’aurais expliqué avec plaisir, mais en C++, mes connaissances reseau pechent. Et si tu es a l’aise vis a vis du C++, tant mieux, je pensais juste par exemple que tu debutais ou que tu essayeais de faire tes armes en programmation, mais promis, je note, Zortom>pas de C# !

Mea culpa, bon courage quand meme B)

[quote=“AnA-l, post:4, topic: 33135”]Ok !
Je demandais juste si tu avais des contraintes vis a vis du C++, si oui, tant pis, en C# je t’aurais expliqué avec plaisir, mais en C++, mes connaissances reseau pechent. Et si tu es a l’aise vis a vis du C++, tant mieux, je pensais juste par exemple que tu debutais ou que tu essayeais de faire tes armes en programmation, mais promis, je note, Zortom>pas de C# !

Mea culpa, bon courage quand meme B)[/quote]

Bah en fait dans l’absolu j’ai pas vraiment de contraintes imposées par mon boss. Pour expliquer rapidement j’ai fait une école d’ingé avec spécialité réseaux/télécoms. La je fais mon stage de fin d’études chez un opérateur téléphonie sur ip. Je pensais pas y faire du dev mais c’est le cas. Sachant qu’à l’école on a fait que du C en ligne de commande sous linux et un tout petit peu de C++ en mode super-scolaire, quand j’ai débarqué ici c’était un peu la misère (cf ici).

Maintenant que je commence un tout petit peu à maîtriser le C++ sous Visual 2003 au bout de 2 mois quand même j’ai pas trop envie de tout reprendre à zéro. Cependant étant doné qu’on arrete pas de nous matraquer avce le C# je me demande si je devrais pas m’y mettre tôt ou tard (bien que comme je le disais deja le dev ca me gonfle mais en tant que stagiaire/jeune diplômé c’est difficile de trouver autre chose).
C’est compliqué de s’y mettre quand on a fait que du C sous nux et qu’on est pas très calé en C++?
Et au niveau de la gestion réseau c’est vraiment plus simple qu’en C/C++?

Bon c’est pas tout ca mais faudrait que j’avance moi

Ben c’est vrai que c’est tentant et si la prog te gonfle, c’est normal en C++ B) la tu vas t’en tirer avec une page et demi de code, voire deux ou trois si tu dois gerer different encoding, alors que tu peux faire ca en quelques lignes en C#.

Histoire d’etre utile, exemple en C++ repompe/adapte d’ailleurs a pas prendre a la lettre c’est pour donner une vague idee de la maniere dont ca marche

[code]#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include

int socketDescriptor;
unsigned short int serverPort;
struct sockaddr_in serverAddress;
struct hostent *hostInfo;

hostInfo = gethostbyname(“192.168.2.1”);
if (hostInfo == NULL) {
cout << "problem interpreting host: " << buf << “\n”;
exit(1);
}

// Create a socket.
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDescriptor < 0) {
cerr << “cannot create socket\n”;
exit(1);
}

serverAddress.sin_family = hostInfo->h_addrtype;
// risque de buffer overflow scandaleux… controlle des trucs a rajouter clairement… m’enfin bon on va vite la
memcpy((char *) &serverAddress.sin_addr.s_addr,
hostInfo->h_addr_list[0], hostInfo->h_length);
serverAddress.sin_port = htons(100);

if (connect(socketDescriptor,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << “cannot connect\n”;
exit(1);
}

… truc a envoyer dans buf … demerde toi pour le mettre dans un byte[] qui tient la route en fonction de l’encoding…

if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
cerr << "cannot send data ";
close(socketDescriptor);
exit(1);
}

… recevoir …
if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
cerr << “didn’t get response from server?”;
close(socketDescriptor);
exit(1);
}

close(socketDescriptor);
return 0;[/code]

En C# pour comparer:

[code]using System;
using System.Net;
using System.IO;
using System.Text;


try {
TcpClient client = new TcpClient(“192.168.2.1”, 100);
byte[] data = Encoding.ASCII.GetBytes(“rulez”);
NetworkStream stream = client.GetStream();

// envoyer…

stream.Write(data, 0, data.Length);

// recevoir et recreer un objet string avec l’encodage qu’il faut
data = new byte[256];
int bytesRead = stream.Read(data, 0, data.Length);
string responseData = Encoding.ASCII.GetString(data, 0, bytes);

stream.Close();
client.Close();
} catch (SocketException ex)
{
Console.WriteLine("Rhaa ca foire " + ex.ToString());
}[/code]

Bon le code en C# fait plus que celui en C++ mais bon… on pourait aussi betement creer un BinaryWriter sur le NetworkStream si les deux cotes sont en C# ce qui serait encore plus simple, et se finirait avec une ligne genre bw.WriteString(“mon xml”) directement pour envoyer et string lecture = br.ReadString() mais la on se la joue roots bas niveau en C#…

(Disclaimer de chie: Bien sur aucun des deux code n’est parfait ou ne doit etre utilise tel quel il manque des choses B) c’est juste pour donner une idee et en plus aider, et faire de la pub! Trois en un.)

Je respire, je me contrôle, j’essaie de ne pas avoir envie de faire un MUD en C#… Je le relis le code de GloP… Je me contrôle… Je… me… RAAAAH GLOP !! B)

Bon, vite C# express B)

Pour completer ce que dit glop, VS2005 (Express) >> VS2003 !

Rah encore des amalgames entre C# et C++.
En C++ aussi t’as le droit d’avoir 300mo de libs, et en C++ aussi ton code ne peut faire que 3 lignes pour envoyer ça.
D’ailleurs meme avec une classe maison ton code peut ressembler à un truc comme ça :

[code]#include “maclasse.h”

int main()
{
try
{
Handler Socket(Socket::Client(“ton ip”, tonPort));
Handler.Send(" << ton xml >> ");
Handler.Close();
}
Catch (Socket::Error &e)
{
std::cerr << e.What() << endl;
}
return 0;
}[/code]

Et c’est autrement plus constructif de faire sa classe que de relire celle des autres (fin meme pas la relire d’ailleurs) sans comprendre ce que tu fais (ce qui en soit est une ineptie apres avoir suivi une formation sur un systeme open source dans un langage comme le C)

mes deux centeuros.

Hein? C’est stupide de dire qu’il faudrait ecrire 3km de code pour faire un truc aussi simple, encapsulé ailleurs dans une classe ou pas. Conseiller l’utilisation d’une lib vaguement std qui fait deja l’encapsulation comme ca, pourquoi pas, mais laquelle alors? Conseiller de l’ecrire de zero ca revient a faire exactement ce que j’ai fait, avec plus de travail pour le rendre re-utilisable. Encore heureux que tu peux ecrire un truc pareil en C++, sauf que ton exemple la il est tres loin de marcher, les miens non. Ca revient a critiquer la maniere dont j’ai ecrit le code, et encore une fois, c’etait pas le but, le but c’est d’inclure tout ce qu’il faut assimiler et ecrire et de montrer ce que tu dois faire pour communiquer avec TCP pas juste les trois lignes tout en haut.

(Message subliminal: les exceptions en C++ sapu, die, die.)

Il cherche a utiliser un outil pour obtenir un resultat. Point barre. Je sais plutot tres bien comment ca fonctionne a des niveaux plus bas, mais j’ai absoluement aucune envie d’ecrire 3km de code pour faire un truc aussi fondamental que d’envoyer du texte avec un encodage donné sur un reseau, j’ai autre chose a faire: j’ai envie d’ecrire la fonctionalite qui m’interesse. Et puis comprendre quoi? Qu’est ce que tu comprends de plus fondamental sur les reseaux avec la version C++ qu’avec la version .Net? Absoluement rien. Et quand bien meme, tout le monde a pas envie ou besoin d’assimiler completement la couche du dessous, c’est tout l’avantage d’une couche d’abstraction reussie! C’est avec des couches d’abstraction reussie qu’on peut progresser et faire des choses plus interessantes a plus haut niveau.

L’argument qui consiste a dire “a la couche d’abstraction du dessus il faut se taper celle du dessous sinon on sait pas ce qu’on fait” a pas de sens. Meme en C pur, je peux te garantir qu’on peut te faire le meme argument avec un mec qui va se le coder en assembleur, apres tout, gerer ses registres c’est important. Lui meme se prendra le meme argument de l’ingenieur hardware qui a fait les portes logiques qui se prendra le meme de l’electronicien qui a du les faire en dopant du silicone qui se prendra le meme argument de physicien qui se prendra le meme argument du mathematicien (qui se prendra le meme argument du philosophe ou du theologien? huhu). A ce rythme la on fait jamais rien.

Ce qui est autrement plus constructif, c’est non seulement de comprendre mais de pas reinventer la roue quand il y en a pas besoin, et ca empeche en rien de savoir ce qu’on fait au niveau adequat. Le plus constructif ca serait surement de lui conseiller une lib en C++ qui encapsule deja tout ca pour lui, comme l’ASIO sur Boost peut etre, ou ca ou ca ou ca ou ca (et d’autres). A choisir en fonction de ses standard de code, de la qualitee, du niveau de fonctionalite desiré, de la maniere dont on gere sa memoire, de son pattern d’exception ou de code d’erreur, etc, etc. Mais si le standard C++ et la lib boost l’ont pas encore fait un truc de complet, c’est bien qu’il y a pas concensus. Les libs en C# elles font parti de .Net, tout le monde les a, elles sont les meme pour tous, et tout le monde les utilise. C’est un standard, homogene car respectant des regles claires et partagées, constant et d’office assimilable a un niveau de qualitee fiable et testé extensivement qu’on a pas besoin de re-ecrire (et si vraiment on a beosin, on peut). C’est pas exclusif a C# hein, y a d’autre langages de haut niveau qui remplissent aussi bien ces criteres. C’est bien la qu’est tout l’interet de la chose, il s’agit de choisir l’outil le plus adapté a la tache, et c’est ptet C++ vu qu’il connait un peu C++ et qu’il a ptet pas forcement envie d’apprendre autres chose (justement). Mais attaquer autre chose sur les criteres que tu choisis, c’est plutot a cote de la plaque je trouve…

je réponds vite fait, j’éditerai.
si ton code fait vraiment partie des librairies “de base sans ajout”, soit.

Toujours est-il qu’il est pas portable directement, donc saimal (oui c’est subjectif, tout comme mon poste précédent).
A coté de ça, pour les librairies j’avoue que j’aurai pû filler les liens mais j’aurai mi autant de temps que lui a coup de google à les retrouver (excuse en bois certe, flemme quand tu nous tient). je comptais justement demander à un copain fana “d’abstraction” (B)) en C++ les libs qu’il aimait bien et pourquoi bref.

Pour revenir au point de départ, trop souvent on voit des comparaisons : "C# (au sens .net en plus :/) c’est bien mieux que je C++ car en C++ tu dois écrire une montagne de code pou faire le moindre truc (eg : une fenetre, une connexion reseau etc …)"
Et ça clairement, ça m’agace ce genre de conneries.

Et juste pour revenir au “bas niveau” : si dans son école ils lui ont remplis le crâne à coup de c sous linux, il a du bouffer des manpages et autre.
Donc “renier” ça c’est celon moi le meilleur moyen de faire un developpeur de base qui developpe sans rien comprendre.
(ça y est je vais encore être mal interprété, menfou B))

Encore 2 choses : Re inventer la roue : non mais si !
t’as jamais implémenté un modele de liste chainées ? ça fait pas partie d’exercices “classiques” ?
Alors pourquoi pas pareil avec une couche réseau ?
Jveux dire bon, il a l’air de quand meme etre en stage, en stage on apprend des choses un minimum non ?

Seconde chose : pour revenir à la couche du dessous ok ça peut aller loin, mais savoir un minimum ce qu’il y a “en dessous” je trouve ça interessant … bah oui apres tout pourquoi on peut pas faire des malloc dans des boucles :]

Je suis d’accord avec vous deux, GloP et fser.

Avec fser, car je trouve qu’on compare souvent .net avec C++, et ça n’a pas des masses de sens, l’un est un environnement de développement complet et l’autre un langage. On ne compare pas une voiture avec un moteur.

Ceci dit, il y a plusieurs façons de programmer, et plusieurs types de programmeurs. Quand on considère la programmation dans l’objectif du résultat, autant prendre ce qu’il y a de plus simple et efficace, que ce soit un langage, un environnement, une librairie, etc. Et il ne faut pas se leurrer, il y a plein de software développé très rapidement par des gens qui ne savent pas forcément ce qu’ils font, mais au final ça fonctionne et y’a que ça qui compte.

[quote=“Drealmer, post:12, topic: 33135”]Je suis d’accord avec vous deux, GloP et fser.

Avec fser, car je trouve qu’on compare souvent .net avec C++, et ça n’a pas des masses de sens, l’un est un environnement de développement complet et l’autre un langage. On ne compare pas une voiture avec un moteur.

Ceci dit, il y a plusieurs façons de programmer, et plusieurs types de programmeurs. Quand on considère la programmation dans l’objectif du résultat, autant prendre ce qu’il y a de plus simple et efficace, que ce soit un langage, un environnement, une librairie, etc. Et il ne faut pas se leurrer, il y a plein de software développé très rapidement par des gens qui ne savent pas forcément ce qu’ils font, mais au final ça fonctionne et y’a que ça qui compte.[/quote]

Quel diplomate B)

\o/

Moi j’en veux plus, des développeurs pragmatiques comme toi B)

Comparer le C# (ou Java car pour moi C# == Java) et le C++ c’est comparer un 4x4 et une voiture de sport. On pourrait trouver des comparatifs qui avantagent l’un et l’autre mais ca n’a aucun sens car ce sont des langages qui evoluent dans des directions differentes pour des besoins differents.

Pour faire des moteurs aux algorithmes velus, en C++ on peut ecrire des choses tres belles en exploitant le template engine qui seraient beaucoup plus verbeuses en C# et aussi moins elegantes. Mieux, on peut meme utiliser ce template engine pour faire du meta code et donc generer un code fiable.

Je ne suis pas un expert en C#, mais il y a clairement des choses interessantes en .NET, utiles pratiques. Ne serait-ce que parce qu’a terme ca va reduire les fuites memoires (bon je prie pour que vous pondiez un jour un gc correct parce que la, euh alors je fais un exhaustif sur mes pointeurs et ensuite je reverifie ouais c’est bon tg tu please handle thanks en fuzzy logic la prochaine fois bref je m’egare B) …) dans les programmes.

Mais la gestion des conteneurs et des algorithmes de la STL, ecrabouille completement les paradigmes du .NET (puisque c’est de cela dont on parle et pas du C#). C’est grace au template engine que cela est possible, et ce n’est pas un malheureux generic qui peut pretendre egaler ses features.

La STL a neanmoins des problemes, comme la difficultes de faire des API binaires en utilisant la STL. Je sais que je me suis arrache des cheveux a cause de ca.

Un exemple pour illustrer mon propos:

transform(list1.begin(), list1.end(), list2.begin(), list2.begin(), _2 += _1);

Tous les elements de list2 recoivent en fin ceux de list1… Je ne vois pas comment faire quelque chose de maniere aussi pure et sure en C#. Car vu que ce n’est pas moi qui ecrit les boucles, une erreur de moins possible… Ah et ca marche tant que += est defini pour l’objet et pour tous les conteneurs STL ayant les iterateurs ad hoc. La programmation generique est dans la place. B)

Et enfin dernier point, je prends le programme de Glop et je fais

[code]using System;
using System::Net;
using System::IO;
using System::Text;

try {
TcpClient^ client = gcnew TcpClient(“192.168.2.1”, 100);
array^ data = Encoding::ASCII::GetBytes(“rulez”);
NetworkStream^ stream = client.GetStream();

// envoyer…

stream.Write(data, 0, data->Length);

// recevoir et recreer un objet string avec l’encodage qu’il faut
data = gcnew array(256);
int bytesRead = stream.Read(data, 0, data.Length);
String^ responseData = Encoding::ASCII::GetString(data, 0, bytes);

stream.Close();
client.Close();
} catch (SocketException^ ex)
{
Console::WriteLine("Rhaa ca foire " + ex->Message);
}[/code]

(j’ai pas verifie que ca compilait une erreur s’est peut etre glissee)

Et la je pose la question, quel est le probleme ?

Bon , deja , pour repondre ( et seulment ) repondre a zortom :
ton probleme n’a rien de sorcier : les erveurs telnet acceptent tout style de commande du moment qu’elles sont codées en ascii .
Il existe de plus en C++ une classe du style socket ( google est ton amis ) qui gere toute seul les connexions .
elle fonctionne comme la lecture d’un fichier .
tu n’aura donc qu’a ecrire dans le flux de données pour pouvoir faire passer une commande telnet B)
c’est aussi simple que cela , tu doit avoir amon avis des codes tout fait la dessus sur le net , ou , au pire , des tuto B)
bonne chasse!
bon code !