/** Echo-Klient in C in 50 Zeilen **/

// Der Klient kann mit Ctrl-Z beendet werden.
// Die Kompilierung ist mit UNICODE oder ANSI moeglich.
// Um anschaulich zu bleiben, verzichtet der Quelltext auf die Fehlerkontrolle der
// Netzfunktionen und ist daher nicht fuer einen produktiven Einsatz geeignet.
// 2015 www.asdala.de.

#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#define BUFSIZE 128 // Groesse des Sende- und Empfangspuffers

int main(int argc, char *argv[])
  {
  WSADATA wsaData;
  SOCKET cltSock;
  struct addrinfo defAddr = { 0 }, *addr = NULL;
  char buf[BUFSIZE];

  SetConsoleTitle(TEXT("Echo-Client"));
  if (argc != 2) {
    printf(TEXT("Aufruf: %s Servername\n"), argv[0]);
    return 1;
    }

  /* Lade Netzbibliothek */
  WSAStartup(MAKEWORD(2,2), &wsaData);

  /* Ermittele eigene Adresse und speichere sie in addr */
  defAddr.ai_family = AF_INET;
  defAddr.ai_socktype = SOCK_STREAM;
  defAddr.ai_protocol = IPPROTO_TCP;
  getaddrinfo(argv[1], "7", &defAddr, &addr);

  /* Verbinde zum Server */
  cltSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
  connect(cltSock, addr->ai_addr, (int)addr->ai_addrlen);
  freeaddrinfo(addr);

  /* Sende und empfange Daten */
  printf("Programmende mit Ctl-Z:\n");
  while (fgets(buf, BUFSIZE, stdin)) {
    send(cltSock, buf, (int)strlen(buf), 0);
    if ((res = recv(cltSock, buf, BUFSIZE, 0), buf) == 0)
      break;
    printf(TEXT("%.*s"), res, buf);
    };

  /* Schließe Verbindung */
  shutdown(cltSock, SD_SEND);
  while (recv(cltSock, buf, BUFSIZE, 0) > 0)
    ;

  /* Raeume auf */
  closesocket(cltSock);
  WSACleanup();
  return 0;
  }