/*
  
  trojan - klasicky TCP klient - linux verze 
  2006 (L) cZokL, mr [dot] czokl [at] gmail [dot] com
 

*/

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFSIZE 1024

using namespace std ;

inline void usage() {
 
  cout << "tcp_klient_lin <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) ;
  
  } 
   
  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

  int sock ;

  if( (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {

    cerr << "Nepovedlo se vytvorit socket" << endl ;
    
    exit(-1);

  }

/* tady zacinaji rozdily mezi udp a tcp*/

  /*
  
  pres fci connect se pripojime k hostiteli
      
  */

  if( (connect(sock, (sockaddr*)&service, sizeof(service))) == -1) {

    cerr << "Nepovedlo se pripojit k hostiteli" << endl ;

    close(sock) ;
   
    exit(-1) ;

  }

  /* 
  
    odesleme prikaz pomoci fce send protoze sme
    aktualne pripojeni k hostiteli uz neni potreba 
    udavat kam ze se maji data poslat
  
  */

  char buffer[BUFSIZE] ;
  
  cin.getline(buffer, BUFSIZE) ;

  if( (send(sock, buffer, strlen(buffer), 0)) == -1) {

    cerr << "Nepovedlo se poslat data!" << endl ;

    close(sock) ;
   
    exit(-1) ;

  }

  /*
  
    prijmeme data - plati to same jako u fce send()    
      
  */

  int size ;
  
  if((size = recv(sock, buffer, BUFSIZE, 0)) == -1) {
   
    cerr << "nelze prijmout vysledek" << endl ;
    
    close(sock) ;
    exit(-1) ;      
    
  }
 
  buffer[size] = '\0' ;

  cout << buffer << endl  ;

  close(sock) ;
  
  return 0 ;

}
