comprendre le code source de netcat

comprendre le code source de netcat - C - Programmation

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.
++

Reply

Marsh Posté le 22-04-2009 à 16:23:27   

Reply

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.

Reply

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.

Reply

Marsh Posté le 22-04-2009 à 17:02:44    

mdr exactement sa.
lol m'ai il minteraisse commeme

Reply

Marsh Posté le 22-04-2009 à 17:08:35    

Mouarf, il y a quelques commentaires croustillant dans le code :

Code :
  1. /* Maybe that's why my C code reads like assembler half the time... */


Ç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.

Reply

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.

Reply

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 :
  1. rr = read (0, bigbuf_in, BIGSIZ);


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.


Message édité par tpierron le 22-04-2009 à 17:56:17
Reply

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?

Reply

Marsh Posté le 22-04-2009 à 20:09:32    

dyroj a écrit :

mdr exactement sa.
lol m'ai il minteraisse commeme


 :ouch:  :ouch:
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.

Message cité 1 fois
Message édité par el muchacho le 22-04-2009 à 20:11:26

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

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.

Reply

Marsh Posté le 22-04-2009 à 21:17:48   

Reply

Marsh Posté le 22-04-2009 à 21:25:30    

merci pour ton aide ami.
je vai essayer de faire comme ta di.
++

Reply

Marsh Posté le 22-04-2009 à 21:38:44    

el muchacho a écrit :


 :ouch:  :ouch:  
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.


çi sai posible 2 coder bien maim si on sé pas bien écrir en francé

Reply

Marsh Posté le 22-04-2009 à 21:50:42    

lol

Reply

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.

Reply

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.

Reply

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.

Reply

Marsh Posté le 22-04-2009 à 23:26:13    

ok je m'excuse.
je ferai un effor.
++

Reply

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.

Reply

Marsh Posté le 23-04-2009 à 15:02:35    

Code :
  1. recv(sock, buffer,1, 1);


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  :love: pas le SMS.

Reply

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?
++

Reply

Marsh Posté le 23-04-2009 à 15:40:53    

Je verrais plutôt un algo du style :

Code :
  1. Attente sur socket serveur (appel à accept())
  2. Boucle infinie:
  3.     select() sur stdin et socket(s) cliente(s) (descripteur en lecture).
  4.     Si FD_SET(stdin) alors
  5.         lit UN caractère et ajoute dans un buffer.
  6.         Si ce caractère est '\n' => envoie le buffer.
  7.     Sinon Pour toute les sockets clients
  8.         Si FD_SET(socket) alors
  9.             lu = recv(socket, buffer, sizeof buffer)
  10.             Si lu < 0 Alors bye bye (client déconnecté).
  11.             Envoie du buffer aux autres sockets et/ou écriture sur stdout.
  12.         Fin si
  13.     Fin Pour


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.

Reply

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;  
++

Reply

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.
Voila la fonction de mon projet qui gere sa, ne fait pas atention au variable com , nbconnect ect..  


Merci de poster du code compilable


 
-------------- Build: Debug in hello ---------------
 
Compiling: main.c
Linking console executable: bin\Debug\hello.exe
C:\dev\hello\main.c: In function `serveur_tcp':
C:\dev\hello\main.c:5: error: `WSADATA' undeclared (first use in this function)
C:\dev\hello\main.c:5: error: (Each undeclared identifier is reported only once
C:\dev\hello\main.c:5: error: for each function it appears in.)
C:\dev\hello\main.c:5: error: syntax error before "wsa"
C:\dev\hello\main.c:6: error: `SOCKET' undeclared (first use in this function)
C:\dev\hello\main.c:7: error: `SOCKADDR_IN' undeclared (first use in this function)
C:\dev\hello\main.c:14: warning: implicit declaration of function `printf'
C:\dev\hello\main.c:17: warning: implicit declaration of function `fatal'
C:\dev\hello\main.c:22: warning: implicit declaration of function `WSAStartup'
C:\dev\hello\main.c:22: warning: implicit declaration of function `MAKEWORD'
C:\dev\hello\main.c:22: error: `wsa' undeclared (first use in this function)
C:\dev\hello\main.c:23: error: `Ewsastartup' undeclared (first use in this function)
C:\dev\hello\main.c:28: error: `sock' undeclared (first use in this function)
C:\dev\hello\main.c:28: warning: implicit declaration of function `socket'
C:\dev\hello\main.c:28: error: `AF_INET' undeclared (first use in this function)
C:\dev\hello\main.c:28: error: `SOCK_STREAM' undeclared (first use in this function)
C:\dev\hello\main.c:28: error: `IPPROTO_TCP' undeclared (first use in this function)
C:\dev\hello\main.c:28: error: `INVALID_SOCKET' undeclared (first use in this function)
C:\dev\hello\main.c:29: error: `Esocket' undeclared (first use in this function)
C:\dev\hello\main.c:34: error: `sin_serveur' undeclared (first use in this function)
C:\dev\hello\main.c:34: error: `INADDR_ANY' undeclared (first use in this function)
C:\dev\hello\main.c:36: warning: implicit declaration of function `htons'
C:\dev\hello\main.c:37: error: `sin_client' undeclared (first use in this function)
C:\dev\hello\main.c:42: warning: implicit declaration of function `bind'
C:\dev\hello\main.c:42: error: `SOCKADDR' undeclared (first use in this function)
C:\dev\hello\main.c:42: error: syntax error before ')' token
C:\dev\hello\main.c:42: error: `SOCKET_ERROR' undeclared (first use in this function)
C:\dev\hello\main.c:43: error: `Ebind' undeclared (first use in this function)
C:\dev\hello\main.c:48: warning: implicit declaration of function `listen'
C:\dev\hello\main.c:49: error: `Elisten' undeclared (first use in this function)
C:\dev\hello\main.c:71: error: `client' undeclared (first use in this function)
C:\dev\hello\main.c:71: warning: implicit declaration of function `accept'
C:\dev\hello\main.c:71: error: syntax error before ')' token
C:\dev\hello\main.c:72: error: `Eaccept' undeclared (first use in this function)
C:\dev\hello\main.c:74: warning: implicit declaration of function `inet_ntoa'
C:\dev\hello\main.c:74: warning: format argument is not a pointer (arg 2)
C:\dev\hello\main.c:76: warning: implicit declaration of function `ioctlsocket'
C:\dev\hello\main.c:76: error: `FIONBIO' undeclared (first use in this function)
C:\dev\hello\main.c:77: warning: implicit declaration of function `Sset'
C:\dev\hello\main.c:81: warning: implicit declaration of function `recv'
C:\dev\hello\main.c:87: warning: implicit declaration of function `Ssize'
C:\dev\hello\main.c:90: warning: implicit declaration of function `send'
C:\dev\hello\main.c:90: error: `NULL' undeclared (first use in this function)
C:\dev\hello\main.c:93: warning: implicit declaration of function `kbhit'
C:\dev\hello\main.c:96: warning: implicit declaration of function `fgets'
C:\dev\hello\main.c:96: error: `stdin' undeclared (first use in this function)
C:\dev\hello\main.c:97: warning: implicit declaration of function `Sajoute'
C:\dev\hello\main.c:101: warning: implicit declaration of function `Sleep'
C:\dev\hello\main.c:106: error: `inf' undeclared (first use in this function)
C:\dev\hello\main.c:107: warning: implicit declaration of function `closesocket'
C:\dev\hello\main.c:114: warning: implicit declaration of function `WSACleanup'
Process terminated with status 1 (0 minutes, 0 seconds)
29 errors, 22 warnings


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 24-04-2009 à 10:56:26    

mdr ta cas le rendre compilable, moi j'ai jamais dis quil etai compilabli.

Reply

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.


Message édité par Elmoricq le 24-04-2009 à 11:13:59
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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