client.cpp 2.99 KB
/** @file 
* \brief Fichero de implementación de un cliente
* \author Imanol Barba Sabariego
* \date 13/06/2013
*
* En este fichero se implementa un cliente para poder usar con el servidor creado, usando la clase Socket.
*/
#include "Socket.h"
#include <iostream>
#include "SocketException.h"
#include <sstream>
#include <signal.h>
#include <cstdlib>
#include <sys/time.h>

using namespace std;

bool connected, finished;

//! Método para terminar el cliente
/*! Este método se usa para terminar el cliente immediatamente en el caso que el servidor cierre la conexión de forma inesperada, capturando
el signal SIGPIPE. */
void exitClient(int signal/*!<Parámetro que captura el signal recibido*/)
{
	cout << "Server connection terminated unexpectedly" << endl << "Exiting" << endl;
	exit(-1);
}

bool connect(Socket& s)
{
	string host;
	int port;
	cout << "Hostname: ";
	cin >> host;
	cout << "Port: ";
	cin >> port;
	cin.ignore();
	try
	{
		s.Connect(host,port);
		cout << "Connected" << endl;
		connected = true;
	}
	catch(SocketException& e)
	{
		cout << e.description() << endl;
	}
}

void speedTest(Socket& s)
{
	string data = "", answer;
	double size;
	double start, duration;
	cout << "Size in MB: ";
	cin >> size;
	cin.ignore();
	for(long int i = 0; i < size*1e6; i++ )
	{
		data += (char)( 65 + i % 26);
	}
	cout << "Data generated, commencing transfer" << endl;
	struct timeval  st, ed;
	gettimeofday(&st, NULL);
	s << data;
	cout << "Data sent" << endl;
	s >> answer;
	gettimeofday(&ed, NULL);
	start = (st.tv_sec) + (st.tv_usec) / 1e6;
	duration = ((ed.tv_sec) + (ed.tv_usec) / 1e6) - start;
	if(answer == "ACK")
	{
		cout << "Transferred " << size << " MB  in " << duration << " seconds" << endl;
		cout << "Data rate: " << size/duration << " MB/s" <<  endl;
	}
}

//! Método principal del cliente
/*! Este método inicializa el Socket, establece la conexión y realiza las acciones que se le hayan programado para comunicarse con el servidor.*/
int main()
{
	signal(SIGPIPE, exitClient);
	signal(SIGINT, exitClient);
	Socket s;
	connected = finished = false;
	string send, recv;
	s.Create();
	while (!exit)
	{
		connect(s);
		while(connected)
		{
			cout << "> ";
			getline(cin,send);
			if(cin.eof())
			{
				send = "/disconnect";
			}
			try
			{
				s << send;
				if(send == "/disconnect")
				{
					s >> recv;
					if(recv == "OK")
					{
						cout << "Disconnecting" << endl;
						s.Close();
		            	connected = false;
					}
				}
				else if(send == "/exit")
				{
					s >> recv;
					if(recv == "OK")
					{
						cout << "Exiting" << endl;
						s.Close();
						connected = false;
						finished = true;
					}
				}
				else if(send == "/test")
				{
					speedTest(s);
				}
				else
				{
					s >> recv;
					cout << "Received: " << recv << endl;
				}
			}
			catch(SocketException& e)
			{
				cout << e.description() << endl;
				cout << "Exiting" << endl;
				s.Close();
	        	return -1;
			}
		}
	}
}

/* TO-DO
 *
 * spawn 2 IO threads
 * connect/disconnect commands
 * list nicks
 * unicast message
 */