/*
  
  trojan - klasicky TCP klient - Windows verze 
  2006 (L) cZokL, mr [dot] czokl [at] gmail [dot] com

  ad komenty - u kazdy fce z knihovny winsock, ktera nebyla popsana 
  v predchazejicich kodech, najdete zbezny popis a
  odkaz na dokumentaci + nejake to info i u jinych veci

*/

#include <iostream>
#include <windows.h>

#define BUFSIZE 1024

using namespace std ;

inline void usage() {
 
  cout << "tcp_klient_win <hostname> <port>" << endl ; 
  
}


int main(int argc, char *argv[]) {

  /*
  
  prebrani vstupnich parametru
  
  */
  
  if ( argc != 3 ) {
  
    cerr << "chybny pocet argumentu" << endl ;
    usage() ;
    exit(-1) ;
    
  }
  
  string hostname = argv[1] ;
  
  int port = atoi(argv[2]) ;
  
  if ( port < 1 || port > 65536 ) {
  
    cerr << "port neni v rozsahu 1-65536" << endl ;
    usage() ;
    exit(-1) ;
  
  } 

  //inicializace Winsock

  WSAData wsadata ;

  if(WSAStartup(MAKEWORD(2,2), &wsadata) !=0) {

    cerr << "Nepovedlo se inicializovat sockety!" << endl ;
    exit(-1) ;

  }
  
  hostent *H = gethostbyname(hostname.c_str())  ;
  if ( H ==  NULL  ) {

    cerr << "hostname neexistuje" << endl ;
    usage() ;
    exit(-1) ;

  }
  
  string ip = inet_ntoa(*(in_addr *)H->h_addr_list[0]) ;

  //naplneni struktury SOCKADDR_IN

  SOCKADDR_IN service ;

  service.sin_family = AF_INET ;
  service.sin_addr.s_addr = inet_addr(ip.c_str()) ;
  service.sin_port = htons(port) ;

  //vytvoreni socketu

  SOCKET sock ;

  if( (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {

    cerr << "Nepovedlo se vytvorit socket" << endl ;

    WSACleanup() ;

    exit(-1);

  }

/* tady zacinaji rozdily mezi udp a tcp*/

  /*
  
  pres fci connect se pripojime k hostiteli
  viz. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp 
    
  */

  if( (connect(sock, (sockaddr*)&service, sizeof(service))) == SOCKET_ERROR) {

    cerr << "Nepovedlo se pripojit k hostiteli" << endl ;

    closesocket(sock) ;

    WSACleanup() ;

    exit(-1) ;

  }

  /* 
  
    odesleme prikaz pomoci fce send protoze sme
    aktualne pripojeni k hostiteli uz neni potreba 
    udavat kam ze se maji data poslat
    viz. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/send_2.asp 
  
  
  */

  char buffer[BUFSIZE] ;
  
  cin.getline(buffer, BUFSIZE) ;

  if( (send(sock, buffer, strlen(buffer), 0)) == SOCKET_ERROR) {

    cerr << "Nepovedlo se poslat data!" << endl ;

    closesocket(sock) ;

    WSACleanup() ;

    exit(-1) ;

  }

  /*
  
    prijmeme data - plati to same jako u fce send()    
    viz. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/recv_2.asp
  
  */

  int size ;
  
  if((size = recv(sock, buffer, BUFSIZE, 0)) == SOCKET_ERROR) {
   
    cerr << "nelze prijmout vysledek" << endl ;
    closesocket(sock) ;
    WSACleanup() ;
    exit(-1) ;      
    
  }
 
  buffer[size] = '\0' ;

  cout << buffer << endl  ;

  closesocket(sock) ;

  WSACleanup() ;

  system("pause") ;

  return 0 ;

}
