//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// Poniższy blok ifdef to standardowa metoda tworzenia makr, która znacznie ułatwia  
// eksport bibliotek DLL. Wszystkie pliki w tej bibliotece DLL są kompilowane z użyciem
// symbolu UNMANAGEDNETWORKING_EXPORTS zdefiniowanego w wierszu poleceń. Ten symbol nie powinien być
// definiowany w żadnym projekcie wykorzustującym ten DLL. W ten sposób dowolny inny projekt,
// którego pliki źródłowe obejmują ten plik, będzie traktował funkcje UNMANAGEDNETWORKING_API jako
// zaimportowane z biblioteki, podczas gdy ta biblioteka potraktuje symbole zdefiniowane
// w tym makro jako wyeksportowane.

#ifdef UNMANAGEDNETWORKING_EXPORTS
#define UNMANAGEDNETWORKING_API __declspec(dllexport)
#else
#define UNMANAGEDNETWORKING_API __declspec(dllimport)
#endif
extern "C"
{
	UNMANAGEDNETWORKING_API int Start();
	UNMANAGEDNETWORKING_API int TransmitByteCount();
	UNMANAGEDNETWORKING_API int ReceivedByteCount();
	UNMANAGEDNETWORKING_API double Elapsed();
	UNMANAGEDNETWORKING_API void Stop();
};

HRESULT ReportSocketError(const std::string& comment, std::string& strMessage);

class NetworkTest
{
public:
	NetworkTest(const std::string& _server, int _port, int _numberOfPackets, int _packetSize) :
		        server(_server),
				port(_port),
				numberOfPackets(_numberOfPackets),
				packetSize(_packetSize)
	{
		elapsed = 0.0F;
		transmitByteCount = 0;
		receivedByteCount = 0;
		socket = INVALID_SOCKET;
		memset(&sin, 0, sizeof(sin));
	}
	virtual ~NetworkTest()
	{
		if(socket != INVALID_SOCKET)
		{
			::closesocket(socket);
			socket = INVALID_SOCKET;
		}
	}
	virtual int Start() = 0;
	std::string GetServer() const
	{
		return server;
	}
	int GetPort() const
	{
		return port;
	}
	int GetNumberOfPackets() const
	{
		return numberOfPackets;
	}
	int GetPacketSize() const
	{
		return packetSize;
	}
	int GetTransmitByteCount() const
	{
		return transmitByteCount;
	}
	void SetTransmitByteCount(int value)
	{
		transmitByteCount = value;
	}
	int GetReceivedByteCount() const
	{
		return receivedByteCount;
	}
	void SetReceivedByteCount(int value)
	{
		receivedByteCount = value;
	}
	double GetElapsed()const
	{
		return elapsed;
	}
	void SetElapsed(double value)
	{
		elapsed = value;
	}
protected:
	std::string server;
	int port;
	int numberOfPackets;
	int packetSize;
	int transmitByteCount;
	int receivedByteCount;
	double elapsed;
	SOCKET socket;
	SOCKADDR_IN sin;
};

