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

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

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.