Winuser's Blog

11 grudnia 2011

część II : Logicznie błędny kod – PHP

Filed under: PHP,Programowanie — winuser @ 15:11
Tags: ,

Wpis jest kontynuacją poprzedniego postu o błędach logicznych w kodzie programu. Ponieważ ostatnio zmuszony byłem do ostrego siedzenia nad kodem w języku PHP, przez pewnego klienta, dlatego wpis będzie właśnie traktował o tym języku. Okazuje się, że w PHP niewiele trzeba aby pisać kod logicznie błędny, jednocześnie trudny do poprawienia, szczególnie gdy projekt jest większy niż te kilkaset linijek.
Na początek klasyka gatunku pod tytułem „błąd z pętlą” :

while (cos_tam);
{
 // jakis kod
 int a = 1 + 2;
}

Klasyka tym razem dla operatora równości :

if ($nextRowID = $rowID)
 break;

Jak widać, tym razem programista tak się śpieszył, że napisał tylko jeden znak „=”, w wyniku czego wyszedł mu operator przypisania. Efektem tego będzie zawsze true, czyli warunek jest bezsensowny.

Programiści języków z rodzaju C/C++ automatycznie dodają znak średnika na końcu wiersza. Zdarza im się to nawet poza kodem.
Kolejny przykład, jeden z moich faworytów. Przykład typowy dla języka PHP w którym zmienna tworzona jest w miejscu pierwszego użycia :

$installler[$row['ID']] = $row['value'];
// kilkaset linii dalej lub w innym pliku
echo $installer['1'];

Dla tych którzy jeszcze nie zauważyli co z powyższym kodem jest źle, już śpieszę z wytłumaczeniem. Chodzi o potrójną literkę `l` w nazwie zmiennej. W wyniku tej pomyłki interpreter PHP utworzy dwie zmienne, jedną $installler oraz drugą $installer. Oczywiście w $installer nie będzie tego co chcieliśmy osiągnąć w linii numer 1 🙂
Czas na przejście do kolejnego przykładu. Jest on również typowy dla PHP. Typowy, ponieważ w języku C kompilator rzuciłby warning „not all paths return a value”.

function Worker($arg_1)
{
 if ($arg_1 < 1024)
 return false;
}

function Another()
{
 // gdzieś w innym, odległym miejscu..
 $result = Worker(300);
 if ($result == true)
 {
 // nigdy się nie wywoła..
 }
}

Ten błąd akurat można w całkiem prosty sposób wykryć, wystarczy zajrzeć w ciało funkcji „Worker”.
Kolejny przykład dotyczy zapytania MySQL. Z bazami danych programista PHP ma doczynienia praktycznie ciągle, więc przykład również się nadaje.

$ret = $db->query("SELECT * FROM `usr` WHERE `uid` = '$uid' AND `field` = $var;");
if ($ret == false || $ret->num_rows == 0)
{
 echo "error";
}

Co będzie wynikiem tego zapytania gdy zmienna $var nie będzie miała wartości nadanej ? Zapytanie będzie błędne. Rozwiązaniem jest branie wszystkiego co możliwe, w cudzysłowy pojedyncze, czyli ostatni kawałek zapytania wyglądałby :

AND `field` = '$var';

Jak widać PHP jest bardzo podatny na błędy w logice kodu. Dzieje się tak w dużej mierze z tego powodu że nie ma on określonych na sztywno typów danych, czyli zmienna która przed chwilą przechowywała tekst, za chwilę może już przechowywać liczbę typu double albo zmienną typu bool. Ta właściwość może być błogosławieństwem albo zmorą. Być może ja osobiście mam takie problemy podczas programowania w PHP, ponieważ jestem dość silnie związany z C / C++ w których to językach jak wiadomo panuje dość silna typizacja zmiennych. Dodatkowym powodem problemów jest to że interpreter PHP nie zwraca uwagi czy funkcja zwraca jakąś wartość, czy może zwraca tylko czasami, ponieważ nie istnieje prototyp funkcji do której kod musi być dopasowany (czyli że funkcja zwraca typ bool i koniec). Na dłuższą metę programując w PHP chyba być zwariował 😉

5 grudnia 2011

część I : Dlaczego ten kod źle działa ? (C++)

Filed under: C++,Programowanie — winuser @ 3:09
Tags: , ,

Tak to już jest w życiu kodera, że często popełnia głupie błędy. Często te błędy są banalne, kuriozalne, groteskowe i jak chcecie je jeszcze nazywajcie. Sam już nieraz się z tym spotkałem (we własnym kodzie). Było to jakiś miesiąc temu kiedy siedziałem nad pewnym błędem a debugowanie aplikacji wcale nie dawało tak jasnych odpowiedzi na pytania jak wtedy tego chciałem. Zdarza się, że w człowiek jest tak „zagoniony” że poprostu nie zauważa jak oto walnął pięknego byka w kodzie (dla osoby z zewnątrz może być on widzialny dosłownie na pierwszy rzut oka).

Pierwszym przykładem, jest operator != bardzo często zresztą stosowany w przeróżnych pętlach, if`ach itd. Dlaczego może on być zagrożeniem ? Popatrzmy na przykład w kodzie :

void Fun()
{
    static unsigned int ret = 0;
    char* buf = NULL;

    ret = klasa->recv()

    if(ret != 0)
    {
        buf = new char[ret];
        // tutaj cos robimy z buf
        delete [] buf;
    }
}

Przykład trywialny, pod pewnym względem z nie wiadomo skąd wzięty. Załóżmy że metoda recv z klasy klasa zwróci nam -1 (dajmy na to kod błędu). Samo sprawdzenie czy nie jest równe 0 nie daje nam w tym przypadku bezpieczeństwa. Zostanie utworzona (złe słowo, będzie próba utworzenia) tablicy z ujemnym rozmiarem, co oczywiscie zaowocuje access violation. Sam na czymś podobnym się złapałem i postanowiłem troszkę bardziej myśleć przy warunkach.

Kolejny ładny przykład, znów groteskowy. Łatwo o niego gdy już jesteśmy mocno zmęczeni :

void Fun(int elem_id)
{
    for(int current_id = 0;
    current_id < elem_id; ++elem_id)
    {
        cout << current_id;
    }
}

Istnieje wiele wersji tej pętli („dlaczego te gówno nie chce działać ?!”), np

void Fun(int elem_id)
{
    for(int current_id = 0; current_id < elem_id; ++current_id)
    {
        klasa->Operacja(--current_id);
    }
}

Może ci się to wydawać śmieszne (albo i nie jeśli sam przeżywasz często to co ja) ale po 20 h pisania niemal non stop naprawde trudno to dostrzec. Po prostu wiesz, że produkujesz shit (bo jak inaczej nazwać podobne konstrukcje), męczysz się, podnosisz ciśnienie 6 kawą i nie możesz dostrzec tego głupiego błędu ! Ale to już w sumie temat na innego posta.

W najbliższym czasie wrzucę część drugą wpisu, tym razem będzie ona dotyczyć języka PHP.

18 listopada 2010

C++ kontra PHP

Filed under: C++,PHP,Programowanie,Projekty,WWW — winuser @ 9:42
Tags: , , , , ,

Tak jak ostatnio obiecałem, tak oto zamieszczam moje przemyślenia / badania kwesti wydajności programów kompilowanych (C++) oraz skryptów (PHP). Jest sprawą oczywistą że walka jest nierówna, że porównanie może nie mieć sensu, że te języki stworzono do innych zadań. Ale olejmy na chwilę te wszystkie gadki, jak naprawdę przekłada się to co mówią ludzie na prawdziwe pomiary ? Sprawdziłem to i w tym wpisie można przeczytać efekty tego. Zamieszczam również kod klasy C++ do mierzenia czasu wykonania funkcji czy bloku programu. Zasady sprawdzania były proste, postawiony serwer www z użyciem popularnego pakietu WebServ (do testowania skryptu PHP) oraz skompilowany program C++ (użyłem kompilatora G++) w wersji release wrzucony do folderu CGI-BIN, odpalany z poziomu przeglądarki internetowej Opera. Na pierwszy ogień poszła konktatencja napisów. Żeby walka była wyrównana (zresztą nie może i tak być o wyrównanej walce mowy), to w kodzie C++ użyłem klasy std::string zamiast zwykłych wskaźników char, bo wynik mógłby się okazać wręcz miażdżący dla PHP. Niestety nawet mimo tego się taki okazał.. Wynik PHP: ~27 sekund, wynik C++: ~1.8 sekundy. Kod programu C++ :

#include <iostream>
#include <string>

#include "PerformanceTimer.h"

using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	string napis;
	
	pt.Start();
	for (int i = 0; i < 100000000; i++)
	{
		napis += i;
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double)10000000) << endl;
	cout << "</body></html>";
	
	return 0;
}

Skrypt PHP:

<html>
	<head>
		<title>Obliczanie</title>
	</head>
	<body>
		<h1>Wyniki obliczen</h1>
		<?php
			$starttime = microtime(true);
			for ($i = 0; $i < 100000000; $i++)
			{
				$napis += $i;
			}
			$stoptime = microtime(true);
			
			echo round($stoptime - $starttime, 5);
		?>
	</body>
</html>

Wykonywanie kodu tego typu (tak wielka ilość iteracji) nie zdarza się raczej zbyt często, aczkolwiek daje pewien obraz sytuacji. W pierwszym teście to, który wygra dość łatwo można było przewidzieć. Ale co gdybyśmy chcieli potestować odczyt i zapis do pliku ? Sprawdziłem. Tym razem testowałem trzy rzeczy, pierwsza odczyt plików i zapis w PHP, druga to odczyt i zapis z użyciem strumieni C++, ostatnia rzecz którą testowałem to odczyt oraz zapis pliku z użyciem funkcji API systemu Windows. Wyniki tym razem nie są już aż tak miażdżące, lecz nadal odrazu widać który sposób jest wydajniejszy. W celu lepszego zobrazowania sytuacji stworzyłem wykres. Jest on wyskalowany w sekundach. Rozmiar pliku na którym testowane były operacje zapis / odczyt można w prosty sposób obliczyć: rozmiar_bufora * ilosc_iteracji = ~ 125 MB.

Dołączam równiez kod C++ użyty do odczytu / zapisu Win32 :

#include <iostream>
#include <string>

#include "PerformanceTimer.h"

using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	DWORD dwWrite;
	
	HANDLE hFile = CreateFile("plik.bin",
							  GENERIC_READ | GENERIC_WRITE,
							  0,
							  0,
							  CREATE_ALWAYS,
							  0,
							  0);
	char szBuffer[255];
	memset(&szBuffer, 0, sizeof(szBuffer));
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwWrite, 0);
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double) 10000000) << endl;
	CloseHandle(hFile);
	
	hFile = CreateFile("plik.bin",
					   GENERIC_READ | GENERIC_WRITE,
					   0,
					   0,
					   OPEN_EXISTING,
					   0,
					   0);
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		ReadFile(hFile, szBuffer, sizeof(szBuffer), &dwWrite, 0);
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double) 10000000) << endl;
	CloseHandle(hFile);
	
	cout << "</body></html>";
	return 0;
}

Kod użyty do odczytu / zapisu z użyciem strumieni :

#include <iostream>
#include <fstream>
#include <string>

#include "PerformanceTimer.h"
		
using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	char szBuffer[255];
	ofstream file;
	
	memset(&szBuffer, 0, sizeof(szBuffer));
	file.open("plik.bin");
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		file << szBuffer;
	}
	pt.Stop();
	
	file.close();
	cout << (pt.GetTime() / (double) 10000000) << endl;
	
	ifstream file_2("plik.bin");
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		file_2.read(szBuffer, sizeof(szBuffer));
	}
	pt.Stop();
	
	file_2.close();
	cout << (pt.GetTime() / (double) 10000000) << endl;

	cout << "</body></html>";
	return 0;
}

A to kod dla PHP :

<html>
	<head>
		<title>Obliczanie</title>
	</head>
	<body>
		<h1>Wyniki obliczen</h1>
		<?php
			for ($i = 0; $i < 255; $i++) $buffer .= "6";
			
			$file = fopen("plik.bin", "w");
			flock($plik, LOCK_EX);
			
			$starttime = microtime(true);
			for ($i = 0; $i < 500000; $i++)
			{
				fwrite($file, $buffer);
			}
			$stoptime = microtime(true);
			
			flock($file, LOCK_UN);
			fclose($file);
			echo round($stoptime - $starttime, 5) . "<br/>";
			
			$file = fopen("plik.bin", "r");
			flock($file, LOCK_SH);
			
			$starttime = microtime(true);
			for ($i = 0; $i < 500000; $i++)
			{
				fread($file, 255);
			}
			$stoptime = microtime(true);
			
			echo "<br/>" . round($stoptime - $starttime, 5) . "<br/>";
			flock($file, LOCK_UN);
			fclose($file);
		?>
	</body>
</html>

Na koniec mała konkluzja tego testu. Od początku wierzyłem że lepsze wyniki uzyska program pisany w C++ i tak też się okazało. Lecz żeby było ciekawiej, to dodam, nie zawsze wyniki uzyskiwane były tak dobre. Nie wiem od czego to zależy, w każdy razie program uruchamiany osobno (nie poprzez serwer www na żadanie przeglądarki) uzyskiwał stabilniejsze i krótsze czasy. Czasem nawet o 1/3. A w przypadku zapisu do pliku wyniki okazywały się być nawet gorsze (!). Mimo tego jednak uważam, że używanie programów CGI kompilowanych może znacząco podnieść wydajność treści dynamicznej, aczkolwiek jest bardziej złożone niż zwykły skrypt w PHP. Ten test nie miał za zadanie oczywiście w żaden sposób pokazać wyższości jednego języka nad drugim. Obydwa lubię i tak już zostanie. Potraktujcie ten test raczej jako ciekawostkę, bo raczej chyba nikt nie będzie pisał www z użyciem C++.
Kod klasy PerformanceTimer można pobrać z pod tego adresu : http://sourceforge.net/projects/performancetime/files/PerformanceTimer.cab/download Jest to klasa napisana z użyciem kodu zawartego w książce „Windows via C/C++” i ja ten kod opakowałem w klasę aby było wygodniej.

17 listopada 2010

Strona internetowa w C++

Filed under: C++,Programowanie,WWW — winuser @ 18:04
Tags: , ,

Osoby obyte w temacie www pewnie w żaden sposób nie zdziwi temat tego wpisu, a inni powiedzą: „co do cholery?”. Ale to prawda, można pisać strony internetowe w języku C++. W języku C też można. Brzmi zachęcająco ? Można też w wielu innych językach które obsługują STDIN i STDOUT (np. Perl, VisualBasic czy Ruby). Ten wpis będzie o pisaniu stron www z użyciem języka C++, resztę sobie podaruję.
Kluczem do odpowiedzi na pytanie „jak to możliwe?” jest słowo „CGI”. Jest to niezmienny standard od 1995 roku. Dawno temu wykorzystywany był do generowania dynamicznie stron, chociaż dziś nadal ma swoją pozycję nieco umniejszoną. Zwykle skrypty CGI pisze się w języku Perl, ale byłoby nudne opisywać tutaj strony www + Perl.
Co wogóle potrzebne jest do tego aby można było tworzyć strony w C++ ? Po pierwsze serwer www z obsługą CGI, jakiś kompilator C++ (ja tutaj użyłem G++). Pliki należy skompilować i wrzucić do folderu cgi-bin. Jeśli z jakiegoś powodu nie uda się uruchomić aplikacji, to najprawdopodobniej serwer wypluje błąd 500. Naturalnie jeśli serwer postawiony jest na systemie Windows to pliki muszą być zbudowane pod tym systemem, jak UNIX to unixowe pliki wykonywalne i tak dalej. Poniżej przedstawiam kod jakiejś prostej strony wypluwającej napis „Jakas tam strona internetowa”.

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])
{
	cout << "Content-type: text/plain" << endl << endl;
	cout << "Jakas tam strona internetowa.";
	
	return EXIT_SUCCESS;
}

Ale co by było gdybyśmy chcieli wyrzucić na wyjście trochę formatowanego kodu HTML ? Trzeba wysłać odpowiednie nagłówki HTTP, a potem kod HTML.

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char* argv[])
{
	cout << "Content-type: text/plain" << endl << endl;
	cout << "<html><head><title>Tytul strony</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Jakas tam strona internetowa.</h1>" << endl;
	cout << "A to maly wpisik" << endl;
	cout << "</body></html>";
	
	return EXIT_SUCCESS;
}

Wynikiem wykonania tego programu będzie w przeglądarce :

Niestety pisanie stron w ten sposób jest dosyć uciążliwe i podatne na błędy. Trzeba też się martwić o nagłówki HTTP. Ale przecież zawsze można napisać własną klasę do obsługi tego, co znacznie uprościłoby całość a także zmniejszyła podatność na błędy. Osobiście interesuje mnie sprawa wydajności strony napisanej w C++ w porównaniu z PHP. Jest to nieco bardziej złożony temat, dlatego postanowiłem zostawić sobie go na kolejny wpis.

18 października 2010

Znów o wolnych strzelcach

Filed under: Programowanie,Życie codzienne — winuser @ 16:34
Tags: ,

Nie jest dobrze na rynku tak zwanych freelancerów czyli „wolnych strzelców” – programistów którzy pracują na zlecenie nad konkretnym projektem. Jest nawet coraz gorzej. Jakiś czas temu na blogu tym wylądował wpis o podobnej tematyce, ale postanowiłem nieco rozszerzyć ten temat, który jest skierowany głównie do osób które mają zamiar zostać freelancerem i nie orientują się zbytnio jeszcze w tym temacie oraz mają wiele podstawowych pytań.

Przeglądając różne fora można nieraz natrafić na różne stwierdzenia że programiści mają się tak dobrze, że freelancerzy dobrze zarabiają i ogólnie wszystko jest kolorowe. W rzeczywistości wszystko wygląda zupełnie inaczej. Otóż jak to w życiu bywa, rynkiem tym rządzą twarde reguły, bezlitośni zleceniodawcy nie chcą płacić godziwych stawek, są oburzeni kiedy ktoś poda konkretną cenę. Ludzie którzy licytują się na popularnych serwisach przechodza samych siebie, ceny osiągają 10 czy 25 zł za projekt na który musiałbym poświecić kilka godzin. Kolejnym elementem zniechęcającym do tego typu pracy jest wręcz ogromna konkurencja, programistów jest tak wielu że aż rzygać się chce, każdy z nich ma coś do powiedzenia, zaoferowania i w bogaty sposób chce się reklamować. Polskie serwisy tego typu są jeszcze względnie małe ale już zagraniczne typu freelancer.com to rozrośnięte twory na których można znaleźć wiele ciekawych zleceń. Ale.. no własnie na znalezieniu się kończy. Jest tam tak wiele osób, że przy jednym projekcie zbiera się nawet kilkadziesiąt osób licytujących się. Ktoś powie „ok ale o co właściwie tobie chodzi, przecież mamy demokrację ?”. A chodzi mi o to, że to wszystko jest marnej jakości, to jest masówka stary. Osoba która posiada jakieś umiejętności ginie w tym tłumie (a raczej osoby). A może być wybrana tylko jedna. Dodatkowo ostatnio zauważyłem pewien głupi trend „sondowania” rynku przez zleceniodawców. To znaczy ktoś wystawia zlecenie, uchodzi za poważnego klienta i ma jasne wymagania. Ale na tym się kończy, bo nikt nie zostaje wyłoniony jako zwycięzca a ludzie tylko stracili swój czas starając się tej osobie jak najlepiej wypromować.

Postanowiłem rozpisać wady i zalety tego rodzaju zarobkowania, wystarczy spojrzeć i wszystko staje się jasne..

wady :

– bardzo duża konkurencja,

– nie pewność zleceń, nie wiadomo czy ktoś wybierze Twoją osobę kolejnym razem (duże prawdopodobieństwo że zostaniesz z niczym),

– przeciętne ceny (w niektórych wypadkach wręcz żałośnie niska),

zalety :

– sam ustalasz swój czas pracy,

– możliwość rozwoju w trakcie projektu a jednocześnie zarabianie,

– sam wybierasz nad czym chcesz pracować.

 

Zalety są interesujące, ale wady powiedziałbym nokautujące. No bo jak można spokojnie spać wiedząc że niedługo do zapłacenia jest rachunek za X a na drugi dzień rachunek za Y, a Ty nie masz kolejnego projektu dogadanego. Jest to stresujące. Dla wielu ludzi (w tym i mnie) ta ogromna konkurencja powoduje sporą niechęć, poprostu wiem że i tak nie zostanę wybrany przy tylu innych ciekawych ofertach. W dodatku są to oferty na takim poziomie cenowym że aż szkoda pisać. Rozwiązaniem tego problemu jest praca stała jako programista albo dla większych hardcorowców „na lewo” u kogoś kto jest w stanie zapewnić stałość zleceń.

Ale jest też kruczek. Ustawić się w ten sposób to prawdziwa sztuka. Czyli czerpać przyjemnośc z pracy i przy tym zarabiać a także nie martwić się o to że będziesz bezrobotny.

Podsumowując, chcesz zostać freelancerem ? Jestem na tak, pod warunkiem że masz stałą pracę i chcesz sobie dorobić czasem coś ekstra. Ale utrzymać się z tego nie utrzymasz.

10 września 2010

Narzędzie do automatycznego startu serwera GTA San Andreas MP

Filed under: C++,Programowanie,Projekty — winuser @ 15:21
Tags: , , , , ,

Na pewnym forum ktoś napisał że utrzymuje serwer GTA San Andreas multi-player, a ja jako że dość często zdarza mi się grywać w tą gierkę, postanowiłem mu pomóc w jego problemie. Mianowicie potrzebował on narzędzia które automatycznie uruchomi proces serwera gry po jego crashu. Nie jest to skomplikowana aplikacja. Napisana została z użyciem VCL (GUI) i funkcji API Windowsa (obsługa procesów, zdarzeń i wątków). Aplikację można pobrać stąd :  https://sourceforge.net/projects/sa-mp-autorun/files/GTA_SA_mp_autostart.cab/download

Aby aplikacja działała jak należy, trzeba wskazać położenie pliku sa_mp_server.exe (czy jak on się tam nazywał bo nie pamiętam 😛 ) i nacisnąć „start”. W momencie kiedy nastąpi crash aplikacji, automatycznie zostanie ona uruchomiona ponownie. Tak samo jeśli ktoś ubije proces serwera. Aby zakończyć go, trzeba poprostu kliknąć „Zakończ” w oknie mojej aplikacji.

23 sierpnia 2010

Kolejny reupload aplikacji Tlen-Prowokator

Filed under: C++,Programowanie,Projekty — winuser @ 20:35
Tags: ,

Poprzednie pliki zostały usunięte z serwisów hostingowych, a jako że po statystykach bloga widzę że zainteresowanie aplikacją nie maleje, dlatego postanowiłem wrzucić aplikację na coś pewniejszego (tutaj SourceForge.net) https://sourceforge.net/projects/tlen-prowokator/files/Tlen-Prowokator-v0-1-1.cab/download

Cheers !

18 sierpnia 2010

Poszukiwany grafik do małego projektu

Filed under: C++,Programowanie,Projekty — winuser @ 9:09
Tags: , , , , , ,

Ostatnio w wolnym czasie zacząłem sobie pisać dwa projekty. Pierwszy to klasa do obsługi gniazd (z opcją SSL) i zdarzeniami, która jest napisana w około 50 %. Drugi projekt który będzie tematem tego wpisu, to gra 😀 Jest to popularna gra w statki. Kiedy byłem dzieckiem zawsze w to grałem z kolegami / rodzeństwem. Gra odbywała się na kartkach papieru. Postanowiłem ją przenieść do komputera. Oczywiście zdaję sobie sprawę że takie gry dzisiaj tworzą o niebo lepsze, ale tworzenie jej to przecież tylko forma rozrywki 😉

Aplikacja jest pisana w języku C++, z wykorzystaniem windows API  (GDI, winsock). Ano właśnie do czego winsock ? Bo będzie to gra sieciowa. Na chwilę obecną mam już gotowe plansze i ogólnie jakiś tam interfejs. Ale. Nie byłoby tego posta gdyby nie pewna ważna sprawa. Otóż ja sam grafikiem jest raczej marnym, dlatego poszukuję osoby która by mi wykonała obrazki statków (rzut z góry). Potrzebne będzie dokładnie 5 rodzajów statków. Dla kogoś kto orientuje się w grafice to pewnie nic trudnego, dla mnie natomiast coś niewykonalnego 😛 Oczywiście osobę tę umieściłbym w stronie „O programie” w poczecie autorów. Tak więc, jeśli ktoś jest chętny to piszcie w komentarzach. Obrazki nie muszą (nawet nie mogą) być przesadnie realistyczne. Przydały by się tutaj raczej zdolości „pixelart”a.

A oto dwa screeny z nie ukończonej gry. Plansza główna :

Zrzut okna rozpoczynania nowej gry :

30 lipca 2010

Moje przemyślenia na temat *IDE* eclipse

Filed under: C++,Programowanie — winuser @ 10:58
Tags: , , ,

Ten wpis nie powstałby gdyby nie to, że ostatnio zostałem w pewnym sensie zmuszony do pracy na tym pseudo środowisku programistycznym. Dawno temu też miałem okazję przyjrzeć się tej aplikacji (i to kilka razy, zawsze go porzucałem). Kiedy byłem jeszcze na etapie badania różnych środowisk. No i tak wpadło mi w rękę Eclipse. Ten wpis nie jest jakąś formą rzetelnego testu porównawczego, odrazu zaznaczam dla wielbicieli i javowców tego *ide* (bo mnie tu zaraz zlinczują).

W dzisiejszych czasach dąży się do tego aby wszystko uprościć, aby zbędne opcje wyeliminować a całość była przejrzysta. Tymczasem twórcy owego środowiska obrali całkiem inną ścieżkę. Wystarczy zajrzeć w okno ustawień, aby się przerazić :

I teraz weź się człowieku tutaj odnajdź. Spędź pół dnia na rozgryzienie tego wszystkiego. Kolejną pomyłką jest jak dla mnie wzięte z kosmosu kolorwanie kodu :

W żadnym z IDE których używałem nie miałem nieprzyjemności oglądania czegoś takiego. No ale cóż, kolorwanie można jeszcze zmienić, w końcu od czegoś te 2,5 miliona opcji w ustawieniach siedzi. Kolejna sprawa która mnie drażni to brak instalatora. Ludzie zakładają że skoro ktoś programuje to pewnie będzie też potrafił sobie skopiować alikację do jakiegoś tam folderu i używać. No ok, tylko że to chyba też wymaga czasu i jest nie wygodne ? Kolejny minus dla tego czegoś. Co mnie jeszcze drażni w tej aplikacji ? Została napisana w języku Java, a więc wymaga potężnego JDK (czyli kolejne setki MB śmieci na dysku i bynajmniej nie chodzi mi tutaj o miejsce na dysku bo zakupiłem ostatnio 500 GB HDD). Uruchamia się powoooli, interfejs się ładuje, pokazuje pasek postępu.. W normalnych aplikacjach nie do pomyślenia. Jak może się interfejs ładować ? W normalnej aplikacji napisane w C++ i Qt to zajęłoby ułamki sekund. Ale nie w Java. Tutaj musi być pasek postępu dla ładowania interfejsu. Żałosne. Co jeszcze mi nie pasuje w tym środowisku ? Jak już wspomniałem, konfiguracja. Żeby cokolwiek zbudować skompilować zlinkować trzeba przekopać się przez tyle opcji że bania mała. No.. jak już ktoś sobie skonfigurował to całe nie wiadomo co, to wtedy może *budować*.

Jeszcze takie spostrzeżenie na koniec, jako początkujący adept tego *świetnego* środowiska, chciałem otworzyć pewien projekt. Co się ukazało moim oczom :

i bądź tu mądry, otwórz projekt. Właśnie dlatego nie znoszę tej aplikacji. Kompletny brak intuicyjności w obsłudze. Wszystko porobili po swojemu olewając istniejące konwencje w tworzeniu oprogramowania. Wszystko trzeba opanować od nowa.

I nasuwa się pytanie. Ludzie! Dlaczego tego używacie ? Przecież jest tyle świetnych środowisk programistycznych którym do pięt nie dorasta Eclipse, pozwolę sobie tutaj chociaż wymienić Code::Blocks (z którym praca to czysta przyjemnośc), Visual Studio czy Pelles C lub nawet C++ Builder..

19 lipca 2010

Klasa SMTP (Simple Mail Transfer Protocol) z obsługą TLS – wysyłanie email z poziomu C++

Filed under: C++,Programowanie,Projekty — winuser @ 9:29
Tags: , , , , ,

Jakiś czas temu (liczony w miesiącach a może nawet dawniej) potrzebowałem nie skomplikowanej klasy do obsługi wysyłania email poprzez prokół SMTP w języku C++. Ostatnio wraz z kolegą pracujemy nad pewnym projektem no i potrzeba wróciła. Dlatego powstała ta klasa, a w sumie dwie. Jeszcze aby wszystkiego stało się zadość, dodam że klasa ta powstała w oparciu o kod do obsługi SMTP w języku C który znajduje się tutaj http://www.muquit.com/muquit/software/mailsend/mailsend.html Ile kodu skopiowano z wspomnianej wyżej biblioteki mailsend ? Otóż ja niczego nie kopiowałem 😛 Spojrzałem jedynie na jakiej zasadzie to wygląda i zaimplementowałem po swojemu. Tak więc mogę powiedzieć że jestem autorem kodu który tutaj przedstawiam. W zasadzie jest to moje drugie podejście do klasy SMTP, poprzednie mimo że zwieńczone sukcesem to jednak nie obsługiwało TLS, dlatego koncepcja została zmieniona, została napisana klasa Sock która służy do komunikacji TCP, oparta o Winsock 2 i bibliotekę OpenSSL. W tym wydaniu klasy obsługuje ona już m.in gmail.com (czyli połączenie z użyciem TLS) i wszelkie inne typu o2.pl. Całość jest bajecznie prosta, jako że protokół SMTP jest protokołem tekstowym i bardzo łatwo zrozumieć o co w nim wogóle chodzi.

Jeśli chodzi o klasę, to została w niej zaimplementowana tylko podstawowa funkcjonalność SMTP, a więc zalogowanie przy użyciu AUTH LOGIN oraz wysłanie wiadomości. Klasa korzysta z biblioteki OpenSSL, którą należy pobrać i zbudować dla używanego kompilatora, pobrać ją można z pod adresu http://www.openssl.org/ w sieci jest wiele poradników jak budować tą bibliotekę (tak, miałem z tym problem :D). Po wprowadzeniu pewnych zmian, klasa powinna działać również na UNIX`ach (chodzi tutaj głównie o klasę Sock). Dlatego jest *prawie* cross-platformowa 😛 No to tyle.

PS. Nie wyrażam zgody na używanie klasy w komercyjnych projektach. Wszelkie spostrzeżenia i uwagi proszę umieszczać w komentarzach.

Link do kodu  http://www.filefactory.com/file/b2a44bb/n/secure_smtp.cab Niestety jak nie będziecie pobierać to link zdechnie 😉 W razie czego proszę o info.

Musiałem wyedytować ten post, poprzednio kod uploadowałem na serwis fileimport.com, miał być 60 dni ale oczywiście na drugi dzień został usunięty. Tak więc szczerze nie polecam serwisu do hostingu plików fileimport.com !

Dopisek numer2. Zmodyfikowałem kod tak aby możliwe było jego działnie bez biblioteki OpenSSL. Wystarczy zdefiniować globalnie jeden symbol – SLL_ENABLED lub też go nie definiować. Wtedy w zależności od tej stałej będą włączane nagłówki i używane funkcje SSL. Oczywiście po wyłączeniu obsługa np. Gmail.com już nie będzie możliwa.

 

Link do źródła klasy : http://s1.katowice.pl/files/secure_smtp.cab

Następna strona »