#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

#define DEFAULT_PORT        5150
#define DEFAULT_BUFFER      4096

using namespace std;

struct ExampleData
{
	char text[32];
	unsigned int number;
};

int main(int argc, char **argv)
{
	cout << "Przyklad do kursu WinSock napisanego przez get'a " << endl;
	cout << "== WYSYLANIE STRUKTUR - KLIENT ==" << endl;

    WSADATA       wsd;
    SOCKET        sClient;
    sockaddr_in server;
    hostent    *host = NULL;
	char	szServer[128];                     
	int		iPort     = DEFAULT_PORT;

	cout << "Podaj IP: ";
	cin >> szServer;

    // Load winsock
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
		cout << "Nie mozna stworzyc WinSock'a." << endl;
        return 1;
    }

    // Create socket and try to connect with server
    sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sClient == INVALID_SOCKET)
    {
		cout << "Nie mozna utworzyc gniazda (" << WSAGetLastError() << ")." << endl;
        return 1;
    }

    server.sin_family = AF_INET;
    server.sin_port = htons((u_short)iPort);
    server.sin_addr.s_addr = inet_addr(szServer);

    // if server adress is no ip, but name, find ip
    if (server.sin_addr.s_addr == INADDR_NONE)
    {
        host = gethostbyname(szServer);
        if (host == NULL)
        {
			cout << "Nie mozna przeksztalcic na ip: " << szServer << endl;
            return 1;
        }
        CopyMemory(&server.sin_addr, host->h_addr_list[0], host->h_length);
    }

    if (connect(sClient, (sockaddr *)&server, 
        sizeof(server)) == SOCKET_ERROR)
    {
		cout << "Nie mozna sie polaczyc (" << WSAGetLastError() << ")." << endl;
        return 1;
    }

	cout << "Polaczono." << endl;

	char value[DEFAULT_BUFFER];
	int received = recv(sClient, value, DEFAULT_BUFFER, 0);
	ExampleData *example = reinterpret_cast<ExampleData*>(value);
	cout << "Skladowa 'text': " << example->text << endl;
	cout << "Skladowa 'number':" << example->number << endl;

	cout << "Rozlaczam." << endl;

	closesocket(sClient);
	WSACleanup();

	getch();
	return 0;
}