#include <windows.h>
#include <winsock2.h>
#include <stdio.h>

//Prototypen
int startWinsock(void);
long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr);

int main(int argc, char** argv)
{
  long rc;
  SOCKET s;
  SOCKADDR_IN addr;
  char buf[256];

  if(argc<2)
  {
    printf("Usage: sock <hostname oder ip des servers>\n");
    return 1;
  }


  // Winsock starten
  rc=startWinsock();
  if(rc!=0)
  {
    printf("Fehler: startWinsock, fehler code: %d\n",rc);
    return 1;
  }
  else
  {
    printf("Winsock gestartet!\n");
  }

  // Socket erstellen
  s=socket(AF_INET,SOCK_STREAM,0);
  if(s==INVALID_SOCKET)
  {
    printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("Socket erstellt!\n");
  }

  // Verbinden
  memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
  addr.sin_family=AF_INET;
  addr.sin_port=htons(12345); // wir verwenden mal port 12345
  rc=getAddrFromString(argv[1],&addr);
  if(rc==SOCKET_ERROR)
  {
    printf("IP für %s konnte nicht aufgeloest werden\n", argv[1]);
    return 1;
  }
  else
  {
    printf("IP aufgeloest!\n");
  }


  rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
  if(rc==SOCKET_ERROR)
  {
    printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
    return 1;
  }
  else
  {
    printf("Verbunden mit 127.0.0.1..\n");
  }


  // Daten austauschen
  while(rc!=SOCKET_ERROR)
  {
    printf("\nZeichenfolge eingeben [max 256]: ");
    gets(buf);
    send(s,buf,strlen(buf),0);
    rc=recv(s,buf,256,0);
    if(rc==0)
    {
      printf("Server hat die Verbindung getrennt..\n");
      break;
    }
    if(rc==SOCKET_ERROR)
    {
      printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
      break;
    }
    buf[rc]='\0';
    printf("\nServer antwortet: %s\n",buf);
  }
  closesocket(s);
  WSACleanup();
  return 0;
}

int startWinsock(void)
{
  WSADATA wsa;
  return WSAStartup(MAKEWORD(2,0),&wsa);
}


long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr)

{
  long rc;
  unsigned long ip;
  HOSTENT* he;


  /* Parameter prüfen */
  if(hostnameOrIp==NULL || addr==NULL)
    return SOCKET_ERROR;


  /* eine IP in hostnameOrIp ? */
  ip=inet_addr(hostnameOrIp);

  /* bei einem fehler liefert inet_addr den Rückgabewert INADDR_NONE */
  if(ip!=INADDR_NONE)
  {
    addr->sin_addr.s_addr=ip;
    return 0;
  }
  else
  {
    /* Hostname in hostnameOrIp auflösen */
    he=gethostbyname(hostnameOrIp);
    if(he==NULL)
    {
      return SOCKET_ERROR;
    }
    else
    {
      /*die 4 Bytes der IP von he nach addr kopieren */
      memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
    }
    return 0;

  }
}


