int main (int argc, char *argv[])
{
	#if defined __linux__ || defined __CYGWIN__
	std::cout << "Running on linux..." << std::endl;
	pthread_t* threads = new pthread_t[2];
	#else
	std::cout << "Running on windows..." << std::endl;
	HANDLE* th = new HANDLE[2];
	#endif

	// Create Server object.
	Server ServerObj (TCPSOCKET, DEFAULTSERVERPORT);			// Without any arguments Server will set defaults, TCPSOCKET as type and 6000 as port.

	// Create Server socket and set socket options.
	ServerObj.CreateSocket (TCPSOCKET);		// No argument means TCPSOCKET
	ServerObj.SetSocketOptions ();

	// Initial Server address struct and bind it with Server's socket.
	ServerObj.InitialiseAddress (6000);		// No argument here will take default port.
	ServerObj.Bind ();

	// Listen for incoming connections.
	ServerObj.Listen ();
	ServerObj.DisplayServerInfo ();

	// Accept any incoming connections.
	ServerObj.Accept ();
	ServerObj.DisplayClientInfo ();

	// Start Sender and receiver threads.
	#if defined __linux__ || defined __CYGWIN__
	pthread_create (&threads[0], NULL, SenderThread, (void*)&ServerObj);
	pthread_create (&threads[1], NULL, ReceiverThread, (void*)&ServerObj);
	#else
	th[0] = (HANDLE)_beginthread (SenderThread, 0, (void*)&ServerObj);
	th[1] = (HANDLE)_beginthread (ReceiverThread, 0, (void*)&ServerObj);
	#endif

	// Wait on threads.
	for (int i=0; i<2; i++)
	{
		#if defined __linux__ || defined __CYGWIN__
		pthread_join (threads[i], NULL);
		#else
		WaitForSingleObject(th[i], INFINITE);
		#endif
	}

	// Close sockets.
	ServerObj.CloseClientSocket ();
	ServerObj.CloseServerSocket ();

	return 0;
}
int main (int argc, char *argv[])
{
	// Create Server object.
	Server ServerObj (TCPSOCKET, DEFAULTSERVERPORT);			// Without any arguments Server will set defaults, TCPSOCKET as type and 6000 as port.

	// Create Server socket and set socket options.
	ServerObj.CreateSocket (TCPSOCKET);		// No argument means TCPSOCKET
	ServerObj.SetSocketOptions ();

	// Initial Server address struct and bind it with Server's socket.
	ServerObj.InitialiseAddress (6000);		// No argument here will take default port.
	ServerObj.Bind ();

	// Listen for incoming connections.
	ServerObj.Listen ();
	ServerObj.DisplayServerInfo ();

	// Accept any incoming connections.
	ServerObj.Accept ();
	ServerObj.DisplayClientInfo ();

	// Send and receive.
	ServerObj.Receive ();
	cout << "No. of bytes received: " << ServerObj.GetNumOfBytesReceived () << endl;
	cout << "Client says: " << ServerObj.GetBuffer() << endl;

	char message[] = "Hello from server.";
	ServerObj.Send ((void *)message, (unsigned int)strlen (message));

	// Close sockets.
	ServerObj.CloseClientSocket ();
	ServerObj.CloseServerSocket ();

	// ********************* UDP Communication ***************************
	cout << "TCP connection closed, now doing UDP communication." << endl;
	ServerObj.CreateSocket (UDPSOCKET);
	ServerObj.InitialiseAddress (6000);
	ServerObj.Bind ();

	cout << "Server recv'in from() packets..." << endl;
	ServerObj.RecvFrom ();
	cout << "They say: " << ServerObj.GetBuffer () << endl;
	ServerObj.DisplayTheirInfo ();

	char UDPmessage[] = "UDP echo message from server.";
	ServerObj.SendTo ((void *)UDPmessage, (unsigned int)strlen (UDPmessage)); // If sending a reply packet most recent received address is used.
	//ServerObj.SendTo ((void *)UDPmessage, strlen (UDPmessage), "localhost", 6001);	// Need to explicitly mention receiver address if not a reply.

	ServerObj.CloseServerSocket ();
	// *******************************************************************

	return 0;
}
int main()
{
	// Create Server object.
	Server ServerObj;

	// Create Server socket and set socket options.
	ServerObj.CreateSocket(TCPSOCKET);		// No argument means TCPSOCKET
	ServerObj.SetSocketOptions();

	// Initialise Server address struct and bind it with Server's socket.
	ServerObj.InitialiseAddress(6000);
	ServerObj.Bind();

	// Listen for incoming connections.
	ServerObj.Listen();
	ServerObj.DisplayServerInfo();

	// Accept any incoming connections.
	ServerObj.Accept();
	ServerObj.DisplayClientInfo();

	// Send and receive.
	int choice = -1;
	Complex A, B, C;
	char Menu[] = "1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Disconnect";

	while (choice != 5)
	{
		ServerObj.Receive((void*)&choice, sizeof(int));

		switch (choice)
		{
			case 1:
			{
				ServerObj.Receive((void*)&A, sizeof(Complex));
				ServerObj.Receive((void*)&B, sizeof(Complex));
				C.real = A.real + B.real;
				C.img = A.img + B.img;
				ServerObj.Send((void*)&C, sizeof(Complex));
				break;
			}
			case 2:
			{
				ServerObj.Receive((void*)&A, sizeof(Complex));
				ServerObj.Receive((void*)&B, sizeof(Complex));
				C.real = A.real - B.real;
				C.img = A.img - B.img;
				ServerObj.Send((void*)&C, sizeof(Complex));
				break;
			}
			case 3:
			{
				ServerObj.Receive((void*)&A, sizeof(Complex));
				ServerObj.Receive((void*)&B, sizeof(Complex));
				float a = A.real;
				float b = A.img;
				float c = B.real;
				float d = B.img;
				C.real = a*c-b*d;
				C.img = a*d+b*c;
				ServerObj.Send((void*)&C, sizeof(Complex));
				break;
			}
			case 4:
			{
				ServerObj.Receive((void*)&A, sizeof(Complex));
				ServerObj.Receive((void*)&B, sizeof(Complex));
				float a = A.real;
				float b = A.img;
				float c = B.real;
				float d = B.img;
				float den =c*c+d*d;
				C.real = (a*c+b*d)/den;
				C.img = (b*c-a*d)/den;
				ServerObj.Send((void*)&C, sizeof(Complex));
				break;
			}
			case 5:
				break;
		}
	}

	// Close sockets.
	ServerObj.CloseClientSocket();
	ServerObj.CloseServerSocket();

	return 0;
}