comprendre le code source de netcat - C - Programmation
Marsh Posté le 22-04-2009 à 16:41:18
C'est la première fois que je dois lire un post aussi difficilement compréhensible, aussi ne m'en veut pas si je ne cherche pas à répondre.
Marsh Posté le 22-04-2009 à 16:52:25
Oué, netcat. J'avais un jour essayé de le compiler pour Windows, ce qui impliquait malheureusement de voir son "code source".
Le moins qu'on puisse dire, c'est que ça m'avait fait mal aux yeux. Code spaghetti write only, parsemé de #ifdef toutes les 3 ou 4 lignes de codes, variables globales à foisons. Bref, pas du tout l'exemple à suivre et encore moins à étudier.
Ce genre de programme, tu le compiles et tu pries pour que ça marche, sans te poser de question.
Marsh Posté le 22-04-2009 à 17:02:44
ReplyMarsh Posté le 22-04-2009 à 17:08:35
Mouarf, il y a quelques commentaires croustillant dans le code :
Code :
|
Ça vaut son pesant de cacahuètes. Et les gueulantes faites sur l'API des sockets BSD, pas mal non plus.
Sinon, je confirme, ce genre de code, c'est bien plus facile d'énumérer les fonctionnalités et de repartir d'une page blanche.
Marsh Posté le 22-04-2009 à 17:15:07
a tu compri comment il on fai pour coder se que g di?
tu c le client qui repond affiche pas les donner recu quand il est lui meme en train d'ecrir une chaine.
je croi que la parti du code qui gere sa est dans la fontion int readwrite (fd) du fichier NETCAT.c.
Marsh Posté le 22-04-2009 à 17:45:26
Ouais effectivement, je vois le problème. Tu démarre un serveur du genre "nc -l -p 1234". Tu entres une chaine sans appuyer sur entrée, tu lances un client "nc 127.0.0.1 1234" et toutes les chaines entrées coté client n'apparaitront sur le serveur que lorsque tu auras validé l'entrée.
À mon avis le serveur est bloqué sur cette ligne :
Code :
|
Faudrait sans doute mettre le TTY en lecture non bloquante (gestion des terminaux POSIX, marchera certainement pas sous Windows).
Edit: ouais, j'ai vraiment que ça à faire en ce moment. En fait, si tu regardes où se trouvent les appels à "read (0, bigbuf_in, BIGSIZ)" et que tu remplaces ça par "read (0, bigbuf_in, 1)", ça évite le blocage. Ça voudra donc dire que tout sera envoyé octet par octet. Faudrait sans doute faire une boucle avec un select sur stdin et un timeout de 0 (pas NULL), parce que si tu envoies un fichier de plusieurs Mo, ça être super lent.
Marsh Posté le 22-04-2009 à 18:05:50
et bah sa a laire tres difficile tou sa.
je vai voir sa.
moi mon but est de faire le meme system mais en plus simple biensur.
je veut que toutes les chaines entrées coté client n'apparaitront sur le serveur que lorsque tu auras validé l'entrée.
mais moi jutulise les thread.
aurai tu une idée pour realiser sa?
Marsh Posté le 22-04-2009 à 20:09:32
dyroj a écrit : mdr exactement sa. |
Cela relève du génocide linguistique, à ce niveau.
Ici on écrit en FRANCAIS. Utilise AU MINIMUM un correcteur d'orthographe si tu n'es pas capable de te relire.
Marsh Posté le 22-04-2009 à 21:17:48
dyroj a écrit : je veut que toutes les chaines entrées coté client n'apparaitront sur le serveur que lorsque tu auras validé l'entrée. |
Et ben, dans la mesure où tu lis l'entrée standard octet par octet (en limitant à 1 chaque appel à read()), au lieu de transmettre immédiatement le buffer lu à la fonction d'envoie, ajoute le caractère dans le buffer et envoie ce buffer une fois que as saisi un \n. Même pas besoin de rajouter un select() pour ça.
Cela dit, j'ai pas trop le courrage de hacker les sources à ce niveau.
Marsh Posté le 22-04-2009 à 21:25:30
merci pour ton aide ami.
je vai essayer de faire comme ta di.
++
Marsh Posté le 22-04-2009 à 21:38:44
el muchacho a écrit : |
çi sai posible 2 coder bien maim si on sé pas bien écrir en francé
Marsh Posté le 22-04-2009 à 23:18:16
Merci de faire des efforts sur l'orthographe. Tu es incompréhensible de tous, à l'exception de tpierron qui a dû faire sms en 2e langue.
Marsh Posté le 22-04-2009 à 23:20:35
moi j'arrive pas a comprendre pk vous en faite tou un pla
c un forum de programmation ou de la langue francaise?
moi je trouve que c lisible.
Marsh Posté le 22-04-2009 à 23:24:51
Tu n'as pas compris le principe.
Tu viens chercher un coup de main sur un forum. La moindre des choses est d'écrire de manière compréhensible, pour que les participants passent du temps sur ton problème, pas sur ton texte. C'est une règle élémentaire de respect. Et puis on ne demande pas une orthographe parfaite non plus.
Bref. Fais un effort.
Marsh Posté le 22-04-2009 à 23:42:28
tpierron > j'ai fais comme tu ma dis et recv(sock, buffer,1, 1);
mais sa marche pas.
Marsh Posté le 23-04-2009 à 15:02:35
Code :
|
Hmm, pas bon. Si tu regardes le code, tu verras que la lecture est divisée en (au moins) 2 parties : lecture sur socket (qui se fait via recv()) et lecture sur TTY/stdin (qui se fait via read()). C'est les appels à read où il faut forcer la taille à 1. Tu verras aussi que la lecture sur clavier/stdin est encore divisée en deux parties : #ifdef WIN32 et système POSIX.
Et sinon, ma seconde langue c'est le C pas le SMS.
Marsh Posté le 23-04-2009 à 15:17:51
En faite j'ai essayer de faire le system de netcat et sa marche mais c un peut male fait enfin je pence, sur tou pour la verification (si le client est toujour connecter). Car c la premiere foi que j'utilise les sockets non blocante.
Voila la fonction de mon projet qui gere sa, ne fait pas atention au variable com , nbconnect ect..
//fonction pour créer un serveur tcp
void serveur_tcp(int port, int NBconnect, int com)
{
//variable
WSADATA wsa;
SOCKET sock,client;
SOCKADDR_IN sin_serveur,sin_client;
int sinsize;
char buffer_recv[1024];
char buffer_send[1024];
int i;
if(com) //commentaire
printf("\nMode serveur (TCP)\n" );
if (port < 1 || port > 65535)
fatal("Port incorrect" );
/****
Initialisation de Winsock
****/
if (WSAStartup(MAKEWORD(2,0), &wsa) != 0)
fatal(Ewsastartup);
/****
Création d'un socket
****/
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
fatal(Esocket);
/****
Initialisation de la struct sin
****/
sin_serveur.sin_addr.s_addr = INADDR_ANY;
sin_serveur.sin_family = AF_INET;
sin_serveur.sin_port = htons(port);
sinsize = sizeof(sin_client);
/****
liaison du socket avec l'ip et un port
****/
if (bind(sock, (SOCKADDR *)&sin_serveur, sizeof(sin_serveur)) == SOCKET_ERROR)
fatal(Ebind);
/****
limite la création de session sur le socket
****/
if(listen(sock, 1) == SOCKET_ERROR)
fatal(Elisten);
if(com) //commentaire
{
printf("Port : %d\n", port);
if(NBconnect == 0)
printf("NBconnect : infini\n" );
else
printf("NBconnect : %d\n", NBconnect);
}
if(NBconnect == 0) //nombre de connection est 0 alors NBconnect = infini
goto __infini;
for(i = 0; i < NBconnect; i++)
{
__infini://bloucle de connection infini
if(com) //commentaire
printf("En attente d'un client...\n" );
/****
Mettre en attente de connection d'un client
****/
if((client = accept(sock, (SOCKADDR *)&sin_client, &sinsize)) == INVALID_SOCKET)
fatal(Eaccept);
if(com) //commentaire
printf("Client\t%s:%d is connect\n", inet_ntoa(sin_client.sin_addr), sin_client.sin_port);
i=1;
ioctlsocket(client, FIONBIO, &i); //pour rendre non blocante
Sset(buffer_recv,0,sizeof(buffer_recv));//efface le buffer
i=0;
__recv_send:
if(recv(client, buffer_recv,sizeof(buffer_recv), 0)>0)
{
if(com==2) //commentaire 2
printf("Client : %s", buffer_recv);
else
printf("%s", buffer_recv);
Sset(buffer_recv,0,Ssize(buffer_recv));//efface le buffer
}
if(send(client, NULL, 0, 0) == -1)
goto __quit;
if(kbhit())//si une touche a ete fraper
{
Sset(buffer_send,0,sizeof(buffer_send)); //efface le buffer
fgets(buffer_send, sizeof(buffer_send), stdin);
Sajoute(buffer_send, "\r" );
if(send(client, buffer_send, Ssize(buffer_send), 0) <= 0)
goto __quit;
}
Sleep(10);
goto __recv_send;
__quit:
inf = 0;
closesocket(client);
if(com) //commentaire
printf("\nDeconnection du client\n" );
if(NBconnect == 0)
goto __infini;
}
closesocket(sock);
WSACleanup();
}
peut -tu m'aider a optimiser se bou de code?
++
Marsh Posté le 23-04-2009 à 15:40:53
Je verrais plutôt un algo du style :
Code :
|
J'ai fait ça à l'arrache, faudra sans doute arrondir les angles. La lecture sur le clavier ne commencera donc que lorsqu'il y a aura au moins un client, comme netcat. Et aussi pas besoin de se prendre la tête avec les sockets non blocantes.
Tiens d'ailleurs, ça m'étonne qu'un select() avec 0 comme descripteur en lecture, ça fonctionne sous Windows. C'est propre aux systèmes POSIX ce genre de truc et select() est une fonction qui fait partie de la dll winsock.
Marsh Posté le 23-04-2009 à 15:49:36
pour l'histoire du : affiche quand y recoit '\n' je l'avait fai mais je l'ai enlever car il ne va pas avec mon projet.
et pour le reste j'aimerais bien faire comme ta dit mais ya un petit probleme, je n'ai jamais apris les socket avec select() et tous se qui va avec.
sinon a tu une idée pour verifier si le client est toujour connecté sans :
if(send(client, NULL, 0, 0) == -1)
goto __quit;
++
Marsh Posté le 24-04-2009 à 02:59:28
dyroj a écrit : En faite j'ai essayer de faire le system de netcat et sa marche mais c un peut male fait enfin je pence, sur tou pour la verification (si le client est toujour connecter). Car c la premiere foi que j'utilise les sockets non blocante. |
Merci de poster du code compilable
|
Marsh Posté le 24-04-2009 à 10:56:26
mdr ta cas le rendre compilable, moi j'ai jamais dis quil etai compilabli.
Marsh Posté le 24-04-2009 à 11:12:46
Il suffit.
Orthographe déplorable malgré avertissements, comportement tout-venant...
Nous ne sommes pas tes camarades de classe. Ni tes amis. Les intervenants ici sont des bénévoles, souvent experts dans leur domaine, qui prennent sur leur temps libre pour aider les autres. Ils n'ont pas à subir ce... hmm... truc.
Je ferme ce sujet.
Marsh Posté le 22-04-2009 à 16:23:27
bonjour a tous,
il y a quelques temps que jessaye de comprendre le system qu'utilise l'outil netcat pour pour la communication reseau.
Fonctionement de netcat pour un client serveur :
si le serveur( ou le client) est en train d'écrir une chaine a envoyer, alors les chaines recu du client( ou du serveur) ne s'affiche pas jusqu'a se qu'il envoi la chaine qu'il était en train d'ecrir.
Une foi la chaine envoyer toute les chaines recu du client( ou du serveur) s'affiche et ainsi de suite.
franchement je ne pense pas qu'une personne n'ayant jamais tester netcat peut comprendre se que je vien de dire.
voila ou vous pouvez trouver son code source http://www.rigelcorp.com/8051/wNetCat.zip .
et je compren pas aussi comment il ont proceder pour créer un client serveur sans thread pour recevoir et envoyer les buffer.
c'est la preumiere foi que janalise un code source aussi diffisile donc ne men vouler pas si vous le trouver facile a comprendre.
++