Telnet en c (bah oui, faut bien commencer...)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 475 fois - Téléchargée 34 fois

Contenu du snippet

Bah, vous connaissez telnet ? En voici un clône en C...

Source / Exemple :


#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

DWORD WINAPI ClientRecv(LPVOID arg) {
  SOCKET Client = *(SOCKET*) arg;
  char c = 0;
  while (recv(Client, &c, 1, 0) > 0) printf("%c", c);
  return 0;
}

DWORD WINAPI ClientSend(LPVOID arg) {
  SOCKET Client = *(SOCKET*) arg;
  char c = 0;
  do if ((c = (char) getc(stdin)) == '\n') send(Client, "\r", 1, 0);
  while (send(Client, &c, 1, 0) > 0);
  return 0;
}

int main(int argc, char* argv[]) {
  WSADATA WSAData;
  char* port = "23";
  char* host = "127.0.0.1";
  SOCKADDR_IN ClientSock;
  SOCKET Client = INVALID_SOCKET;
  HOSTENT* ServerInfos = NULL;
  HANDLE RecvThread = NULL;
  DWORD RecvThreadID = 0;
  DWORD RecvThreadExitCode = 0;
  HANDLE SendThread = NULL;
  DWORD SendThreadID = 0;
  DWORD SendThreadExitCode = 0;
  if (argc > 1) host = argv[1];
  if (argc > 2) port = argv[2];
  printf("connecting to [%s] on port [%s]... ", host, port);
  if (WSAStartup(MAKEWORD(2, 2), &WSAData)) {
    printf("unable to start winsock\n");
    return EXIT_FAILURE;
  }
  if (!(ServerInfos = gethostbyname(host))) {
    printf("unable to resolve remote host\n");
    return EXIT_FAILURE;
  }
  memset(&ClientSock, 0, sizeof(SOCKADDR_IN));
  memcpy(&ClientSock.sin_addr.s_addr, ServerInfos->h_addr, ServerInfos->h_length);
  ClientSock.sin_port = htons(atoi(port));
  ClientSock.sin_family = AF_INET;
  if (!(Client = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
    printf("unable to create client socket\n");
    return EXIT_FAILURE;
  }
  if (connect(Client, (SOCKADDR*) &ClientSock, sizeof(SOCKADDR_IN))) {
    printf("unable to connect to remote host\n");
    return EXIT_FAILURE;
  }
  if (!(RecvThread = CreateThread(NULL, 0, &ClientRecv, &Client, 0, &RecvThreadID))) {
    printf("unable to create recv thread\n");
    return EXIT_FAILURE;
  }
  if (!(SendThread = CreateThread(NULL, 0, &ClientSend, &Client, 0, &SendThreadID))) {
    printf("unable to create send thread\n");
    return EXIT_FAILURE;
  }
  printf("done\n");
  do {
    Sleep(100);
    GetExitCodeThread(RecvThread, &RecvThreadExitCode);
    GetExitCodeThread(SendThread, &SendThreadExitCode);
  } while (RecvThreadExitCode == STILL_ACTIVE && SendThreadExitCode == STILL_ACTIVE);
  printf("\n\ndisconnected from remote host\n");
  if (RecvThreadExitCode == STILL_ACTIVE) TerminateThread(RecvThread, 0);
  if (SendThreadExitCode == STILL_ACTIVE) TerminateThread(SendThread, 0);
  CloseHandle(RecvThread);
  CloseHandle(SendThread);
  return EXIT_SUCCESS;
}

Conclusion :


Ceci est (quasiment) ma première application fonctionnelle en C, donc plutôt que de m'incendier si il y a des erreurs, expliquez moi ce qui ne va pas ;o)

Note: si vous utilisez Doskey, vous pouvez rappeler les commandes entrées comme si vous étiez à l'invite de commande

Note (bis) : ce code a été compilé avec GCC/MinGW

A voir également

Ajouter un commentaire

Commentaires

Gauthier2005
Messages postés
1
Date d'inscription
mercredi 14 septembre 2005
Statut
Membre
Dernière intervention
14 septembre 2005

Hello,

j'essaie d'utiliser ce code pour réaliser une application.
J'aimerais envoyer des commandes au serveur par l'intermédiaire d'une variable chaîne et non à partir du clavier.
N'étant que gros newbie en C, quelqu'un peut-il faire les modification nécessaires pour qu'une chaîne soit envoyée par variable que je puisse utiliser à ma guise ds le reste du programme?
Merci.
BlackGoddess
Messages postés
338
Date d'inscription
jeudi 22 août 2002
Statut
Membre
Dernière intervention
14 juin 2005

sinon, pour 1ere critique:

TerminateThread ne doit etre utilisé qu'en dernier recours, en cas d'erreur irrécupérable par exemple (d'apres les msdn). tu peux donc faire un systeme de message pour tes threads, et leur en envoyer un qd ils doivent se fermer, ou sinon déclarer un "flag" global, et lorsque les threads le voient mis, ils se ferment.

sinon, au lieu de boucler jusqu'a la fermeture des threads, ce qui consomme des ressources cpu, tu peux utiliser WaitForSingleObject(hThread, INFINITE); qui rend la main au système jusqu'a ce que le thread se ferme.
pour attendre plusieurs threads a la fois, utilise l'api WaitForMultipleObjects.
BlackGoddess
Messages postés
338
Date d'inscription
jeudi 22 août 2002
Statut
Membre
Dernière intervention
14 juin 2005

euh ... a part windows.h qui est spécifique a windows (et p-e winsock2.h aussi je c plus), toutes les autres sont des libs standards ...
cs_Narcissus
Messages postés
15
Date d'inscription
mardi 8 juillet 2003
Statut
Membre
Dernière intervention
9 avril 2008

salut, pouvez vous m'envoyer les fichiers d'en tete utilisés, je ne les ai pas encore

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.