Dwie funkcje konwertujące polskie znaki z Windows-1250 na ISO-8859-2 i na odwrót.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
function IsoToWin(S: String): String; var i: Integer; begin for i := 1 to Length(S) do // ISO -> WIN case S of Chr(161): S := Chr(165); Chr(166): S := Chr(140); Chr(172): S := Chr(143); Chr(177): S := Chr(185); Chr(182): S := Chr(156); Chr(188): S := Chr(159); end; Result := S; end; function WinToIso(S: String): String; var i: Integer; begin for i := 1 to Length(S) do // WIN -> ISO case S of Chr(165): S := Chr(161); Chr(140): S := Chr(166); Chr(143): S := Chr(172); Chr(185): S := Chr(177); Chr(156): S := Chr(182); Chr(159): S := Chr(188); end; Result := S; end; |
Autor: Kkkas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
unit Unit1; interface uses {w sekcji uses musimy zadelkarować dodatkowo te dwa moduły} UrlMon, ActiveX; type {w module UrlMon jest już zdefiniowany interfejs IBindStatusCallback, niestety nie możemy go użyć w takiej formie jakiej jest, musimy zdefiniować nowy interfejs pokrywając tylko jego metody. Do rozwiązania potrzebna nam jest funkcja OnProgress, reszta może nic nie robić, ale muszą być zdefiniowane} TStatusCallback = class (TObject, IBindStatusCallback) public function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall; function GetPriority(out nPriority): HResult; stdcall; function OnLowResource(reserved: DWORD): HResult; stdcall; function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall; function OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult; stdcall; function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult; stdcall; function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult; stdcall; function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall; {poniższe funkcje nie są opisane w interfejsie IBindStatusCallback w module UrlMon (plik UrlMon.pas) ale są wymagane przez Delphi w opise każdego interfejsu, bez tego się nie skompliluje} function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall; end; TForm1 = class(TForm) ProgressBar1: TProgressBar; Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function TStatusCallback.OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall; begin result:=0; end; function TStatusCallback.GetPriority(out nPriority): HResult; stdcall; begin result:=0; end; function TStatusCallback.OnLowResource(reserved: DWORD): HResult; stdcall; begin result:=0; end; function TStatusCallback.OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall; begin Form1.ProgressBar1.Max:=ulProgressMax; Form1.ProgressBar1.Position:=ulProgress; result:=0; end; function TStatusCallback.OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult; stdcall; begin Form1.Edit1.Text:='Zakonczono pobieranie'; result:=0; end; function TStatusCallback.GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult; stdcall; begin result:=0; end; function TStatusCallback.OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult; stdcall; begin result:=0; end; function TStatusCallback.OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall; begin result:=0; end; function TStatusCallback._AddRef: Integer; begin end; function TStatusCallback._Release: Integer; begin end; function TStatusCallback.QueryInterface(const IID: TGUID; out Obj): HRESULT; begin end; procedure TForm1.Button1Click(Sender: TObject); var StatusCallback : TStatusCallback; begin StatusCallBack:=TStatusCallback.Create; {tworzymy interfejs StatusCallback} UrlDownloadToFile(nil, PChar('http://www.strona.pl/pobierany_plik.ext'), PChar('C:\pobierany_plik.ext'), 0, StatusCallBack); {wywołujemy pobieranie} StatusCallBack.Free; {zwalniamy interfejs} end; end. |
Autor: cyberdemon
Najprostszym sposobem jest skorzystanie z systemowego polecenia URLDownloadToFile. Aby odwołać się do niego w uses wpisz URLMon, a następnie:
1 |
URLDownloadToFile(Nil,PChar(Zrodlo_adres_strony), PChar(Cel_plik_na_dysku) ,0,Nil); |
Autor: Nakiel
W tym artykule chcę przybliżyć program oparty na TCP/IP… Do takiej komunikacji potrzebne są oczywiście 2 komputery, czyli potrzebne będą 2 programy. Nazywają się one : 'Klient’ i 'Serwer’ (ang. 'Client’ and 'Server’). Zasada ich działania jest bardzo prosta. Otóż Client wysyła do Server’a tekst (String), a ten mu odpowiada tym samym…
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Przypis: Poniższy przykład zbudowano w Delphi 6 PE
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
1. Client
Zacząłem od Klienta, gdyż wydaje mi się, że jego budowa jest prostsza i łatwiejsza do zrozumienia. Do budowy naszego Klienta użyję TClientSocket (w Delphi 6 PE – zakładka INTERNET). Sprawdźmy teraz co oznaczają poszczególne jego własności:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Active :
Kiedy nasz Client jest Active := true, to będzie jak sama nazwa wskazuje aktywny i gotowy do nawiązania połączenia z Serwerem… W przypadku FASLE jego działanie będzie wyłączone.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Address :
To jest najważniejsza część budowy Client’a. Ta własność odpowiada za Adres komputera na którym znajduje się nasz Serwer. W tym polu deklarujemy Adres IP komputera, na którym stoi nasz Serwer lub '127.0.0.1′ Server. Port jest wartością numeryczną potrzebną do obustronnej komunikacji między Klientem i Serwerem. Port można przedstawić jako „drzwi”, do przez które Client chce „wejść” do Server’a. Każdy Server wykonuje poszczególne zadania na innym porcie np. odbiera pocztę na 110, wysyła na 25, a strony www pokazuje na 80… Oczywiście w naszym programie to my ustalamy na jakim porcie chcemy ustawić naszą komunikację. Wybierzmy sobie np. 1205…
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
W tym momencie ustawiliśmy już najważniejsze punkty budowy naszego Client’a. Teraz ustaw na formie Button i Edit. Komponentu Edit służyć nam będzie jako pole zawierające Adres IP server’a. Zdarzenie OnClick Button’a uzupełniamy następująco:
1 2 3 4 5 |
clientsocket1.Address := edit1.text; clientsocket1.Active := true; clientsocket1.open; |
Wywyższy kod Client’a pobiera z Edit1 numer IP komputera – Servera, uaktywnia się i otwiera (można wstawić również Edit2, który będzie przechowywał numer portu).
Następnie wstaw Button2 i w OnClick uzupełnij:
1 2 3 4 5 6 |
clientsocket1.Socket.SendText('Działa :))))))'); { oczywiście możemy ten tekst modyfikować lub najlepiej wstawić kolejny Edit i wtedy uzupełnić clientsocket1.Socket.SendText(Edit3.text) } |
W ten sposób Client wysyła do Server’a tekst o treści 'Działa :))))))’… Ale oczywiście w tej fazie naszego projektu nic nie działa… 🙁 . Dlaczego? Gdyż nie mamy Serwera
2. Server
Cała budowa będzie się opierać na komponencie TServerSocket.
Przeanalizujmy sobie jego właściwości:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Active :
Oczywiście uaktywnia Serwer…
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Port :
Musi być identyczny jak w Cliencie.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Wstaw na formę Label1 i w zdarzeniu OnClientRead Server’a wpisz:
1 |
label1.caption := socket.ReceiveText; |
Wstaw następnie Button i w OnClick:
1 2 3 |
ServerSocket.Port := StrToInt(Edit1.Text); Serversocket1.Active := true; |
Kompilujemy teraz 2 nasze programy… i uruchamiamy
W cliencie uzupełniamy pole ADRES_IP (edit1) i aktywujemy przez naciśnięcie Button’a. Teraz uruchamiamy Server i aktywujemy go… Nie pozostaje nam nic, jak tylko przesłać tekst z Client’a (Button2) do Server’a… I co, działa? W ten sposób zbudowałeś swój pierwszy program oparty na TCP/IP 🙂
Autor: Irvine
W tym artykule postaram się Wam wyjaśnić jak stworzyć prosty komunikator internetowy. Przedstawię jedynie działanie takiego komunikatora, nie będę podawał gotowego kodu źródłowego. Zakładam, że przeczytaliście już artykuł „Jak połączyć dwa komputery” i wiecie jak posługiwać się komponentami ClientSocket i TServerSocket.
Dobra… zaczynamy! W moim poprzednim artykule wyjaśniłem jak połączyć tylko dwa komputery (klienta z serwerem), teraz zajmiemy się serwerem który połączy kilka klientów.
Podejrzewam, że większość Was próbowała z serwerem (który napisaliśmy w artykule „Jak połączyć dwa komputery”) połączyć więcej niż jednego klienta. Efekt nie był zadowalający, bowiem gdy tak zrobimy, serwer będzie wysyłał wiadomość do ostatniego podłączonego klienta. Dzieje się tak, ponieważ zaprogramowaliśmy tak serwer! Ta linijka :
1 |
ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections-1].SendText('Witaj'); |
ma za zadanie wysłać do ostatniego „aktywnego połączenia”. Można się domyślić, że „ServerSocket.Socket.ActiveConnections” odpowiada za pobranie ilości podłączonych klientów. Jeśli zastosujemy pętle, serwer wyśle nam wiadomość do wszystkich klientów.
1 2 3 4 5 6 7 8 9 10 11 |
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); begin for n:=0 to ServerSocket1.Socket.ActiveConnections-1 do begin ServerSocket1.Socket.Connections[n].SendText(Socket.ReceiveText); ... end; |
Stosując ten sposób otrzymamy prosty czat internetowy. Zmieniliśmy tylko kod źródłowy serwera, ale jeśli chcemy stworzyć komunikator musicie pogrzebać w kodzie źródłowym klienta. Trzeba wymyślić strukturę wysyłanego komunikatu do serwera. Powinien zawierać np. identyfikator (nick, id, itp.) osoby do której wysyła się tekst (żeby tekst nie był widziany przez wszystkich użytkowników), identyfikator osoby wysyłającej no i tekst który dana osoba chce wysłać. Przykład:
1 |
ClientSocket1.Socket.SendText(ComboBox1.Text + '-' + MyNick + '-' + Edit1.Text); |
Potem tylko trzeba napisać prosty algorytm który odzieli dane, i przeszuka tabelę (z aktywnymi klientami) w poszukiwaniu danej osoby. Tabela powinna zawierać nick i „identyfikator” klienta (nick dla zidentyfikowania, a identyfikator do wysłania wiadomości, np.
1 |
ServerSocket1.Socket.Connections[identyfikator].SendText(wiadomosc);). |
Jak widać jest to dość proste i logiczne (przynajmniej dla mnie ;)). Ostatnio pisałem „ Komentator internetowy” podobny do tego co mają na Onet.pl – to jest przykładowe zastosowanie łączenia większej ilości klientów.
Pozdrawiam 🙂
Autor: Uno
Opisze w tym artykule jak stworzyć prostą aplikację umożliwiającą połączenie dwóch komputerów. Zaczynamy!
W delphi mamy dwa komponenty, które umożliwiają nam połączenie. Jest to TClientSocket i TServerSocket w palecie Internet. Żeby połączyć się do jakiegoś komputera potrzebny jest nam adres serwera IP i numer portu (od 0 do 65535).
Zrobimy program który będzie serwerem i program który będzie klientem. Serwer otwiera port klientowi, który za pomocą IP i numeru otwartego portu, łączy się z serwerem.
Stwórz nową aplikację i wstaw tam komponent TClientSocket i TServerSocket z palety Internet. Zmień ich nazwe na ClientSocket i ServerSocket. Teraz wstaw 2x na forme komponent Edit. Te dwa pola będą służyły do wpisywania adresu IP i portu. Teraz wstaw 2 przyciski. Ich caption zmień na Hostuj i Rozłącz. W przypadku pierwszego przycisku nazwa nie ma znaczenia, ponieważ wstawimy jeszcze 2 RadioButtony, dzięki którym użytkownik będzie mógł wybrać czy będzie klientem czy serwerem, jęzeli będzie serwerem to caption będzie Hostuj, jeżeli klientem caption będzie Połącz. Tak jak już wspomniałem wstaw 2 RadioButton-y. Pierwszemu nadaj caption Serwer, a drugiemu Klient. Dodaj jeszcze komponent Memo.
Zaczynamy pisać kod!
1) W inspektorze obiektów komponentu RadioButton 1 (serwer), znajdź opcje Checked, nadaj jej wartość true.
2) Wygeneruj zdarzenie OnClick komponentu RadioButton 1, i dopisz takie linijki:
1 2 3 4 5 |
Button1.Caption:='Hostuj'; //Jeżeli komponent zostanie zaznaczony, to Button1.Caption=Hostuj Edit1.enabled:=false;//Jeżeli komponent zostanie zaznaczony, to IP jest nie potrzebne, więc nadajemy właściwość false |
3) Wygeneruj zdarzenie OnClick komponentu RadioButton 2, i dopisz takie linijki:
1 2 3 4 5 |
Button1.Caption:='Połącz'; //Jeżeli komponent zostanie zaznaczony, to Button1.Caption=Połącz Edit1.enabled:=true; //Jeżeli komponent zostanie zaznaczony, to IP jest jest potrzebne, więc nadajemy właściwość true |
4) Wygeneruj zdarzenie OnClick, komponentu button1 (hostuj, połącz), i dopisz tam takie linijki:
1 2 3 4 5 6 7 |
if radiobutton1.checked=true then begin ServerSocket.active:=true end else ClientSocket.active:=true; |
5) Wygeneruj zdarzenie OnChange w komponecie Edit1 (IP), i dopisz tam takie linijki:
1 2 3 |
ClientSocket.address:=edit1.text; // adres IP = edit1.text ClientSocket.host:=edit1.text; // adres IP = edit1.text |
6)Wygeneruj zdarzenie OnChange w komponecie Edit3 (Port), i dopisz tam takie linijki:
1 2 3 |
ClientSocket.port:=strtoint(edit2.text); //port klienta = edit2.text ServerSocket.port:=strtoint(edit2.text); //port serwera = edit2.text |
Pierwszą część mamy już za sobą 🙂 Wpierwszej części utworzyliśmy sporo procedur, zasada działania tego programu jest bardzo prosta, najważniejszą rzeczą jest odzczytanie adresu IP i numeru Portu z pól tekstowych, i rozrużnianie czy dana osoba jest serwerem czy klientem. Co będziemy robić w części drugiej? Pamiętasz, stworzyliśmy komponent Memo, trzeba go jakoś wykorzystać 😉 Dzięki temu komponentowi będą wświetlać wiadomości od serwera, np. potwierdzenie przyjęcia klienta. Zaczynamy część drugą!
1)Zaznacz komponent ServerSocket i wygeneruj zdarzenie OnAccept i dopisz takie linijki:
1 2 3 4 5 6 7 8 9 |
memo1.Lines.Add('Akceptuje połączenie z: ' + Socket.RemoteAddress); if radiobutton1.checked=true then ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections -1].SendText('Witaj'); //jeżeli jest serwerem to wysyłą do klienta tekst "witaj", a do siebie wysyła tekst 'Akceptuje połączenie z: + numer IP" |
2)Zaznacz komponent ClientSocket i wygeneruj zdarzenie OnRead i dopisz takie linijki:
1 |
Memo1.Lines.Add('Otrzymałem tekst: ' + Socket.ReceiveText); // wyświetla otrzymany tekst |
3)Wygeneruj zdarzenie OnClose formy i dopisz takie linijki:
1 |
ServerSocket.active:=false; //wyłącz serwer ClientSocket.active:=false; //wyłącz klienta |
To by było na tyle, takie same linijki wpisz do zadarzenia OnClick Button2 (rozłącz). Poniżej prezentuje cały kod źródłowy programu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ScktComp; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; RadioButton1: TRadioButton; RadioButton2: TRadioButton; Button1: TButton; Button2: TButton; ClientSocket: TClientSocket; ServerSocket: TServerSocket; Memo1: TMemo; procedure RadioButton1Click(Sender: TObject); procedure RadioButton2Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Edit1Change(Sender: TObject); procedure Edit2Change(Sender: TObject); procedure ServerSocketAccept(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); procedure Button2Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.RadioButton1Click(Sender: TObject); begin Edit1.enabled:=false; Button1.Caption:='Hostuj'; //Jeżeli komponent zostanie zaznaczony, to Button1.Caption=Hostuj end; procedure TForm1.RadioButton2Click(Sender: TObject); begin Edit1.enabled:=true; Button1.Caption:='Połącz'; //Jeżeli komponent zostanie zaznaczony, to Button1.Caption=Połącz end; procedure TForm1.Button1Click(Sender: TObject); begin if radiobutton1.checked=true then begin ServerSocket.active:=true end else ClientSocket.active:=true; end; procedure TForm1.Edit1Change(Sender: TObject); begin ClientSocket.address:=edit1.text; ClientSocket.host:=edit1.text; end; procedure TForm1.Edit2Change(Sender: TObject); begin ClientSocket.port:=strtoint(edit2.text); ServerSocket.port:=strtoint(edit2.text); end; procedure TForm1.ServerSocketAccept(Sender: TObject; Socket: TCustomWinSocket); begin memo1.Lines.Add('Akceptuje połączenie z: ' + Socket.RemoteAddress); if radiobutton1.checked=true then ServerSocket.Socket.Connections[ServerSocket.Socket.ActiveConnections -1].SendText('Witaj') end; procedure TForm1.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); begin Memo1.Lines.Add('Otrzymałem tekst: ' + Socket.ReceiveText); end; procedure TForm1.Button2Click(Sender: TObject); begin ServerSocket.active:=false; ClientSocket.active:=false; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ServerSocket.active:=false; ClientSocket.active:=false; end; end. |
Mam nadzieję że wszystko zrozumieliście, jak nie to piszcie e-maila uno11@poczta.onet.pl, lub skontaktujcie się ze mną przez gg: 3854058
Pozdrawiam
Uno
Autor: Uno