CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Obsługa protokołu TCP i UDP - INDY

Obsługa protokołu TCP i UDP - INDY

problemy z tworzeniem programów do obsługi sieci, internetu, e-mail itp..

Obsługa protokołu TCP i UDP - INDY

Nowy postprzez gmp13 » niedziela, 22 maja 2011, 19:20

Witam!

Na początku pragnę zastrzec, że jestem amatorem i moja znajomość środowiska Builder C++ pozwala mi na tworzenie podstawowych programów. Już od jakiegoś czasu piszę w tym IDE (od jakieś 1.5 roku).
Jesteście chyba jedynymi Polakami dobrze obeznanymi z tym środowiskiem, więc postanowiłem zadać wam kilka pytań.
Od jakiegoś czasu na innym forum robiony jest projekt. Polega on na tym, że jedna osoba tworzy "aplikację-serwer" do gry karcianej, a my tworzymy do niego "programy-klientów". Korzystam z komponentów INDY - TidTCPClient i TidTCPServer

1. Moje wstępne próby połączenia się z klientem zakończyły się powodzeniem. Udało mi się także odebrać dane z serwera, z czego bardzo się cieszę. Ale napotkałem parę problemów. Mianowicie kolega z forum poinformował mnie, że serwer odbiera komunikaty w postaci tablicy bajtów. Nie słyszałem nigdy o tym, więc pogrzebałem trochę w dokumentacji i znalazłem TByteDynArray. Udało mi się wysłać tą tablicę, jednak mimo to serwer nie odebrał komunikatu. Niestety, kodu nie mogę przytoczyć, ponieważ zaginął, a nie pamiętam jak go odtworzyć. Proszę tylko o pomysły na rozwiązanie tego zdarzenia.
2. Przy odbieraniu komunikatów z "programu-serwera" za pomocą funkcji Read...
Kod: Zaznacz cały
UnicodeString komunikat = AContext->Connection->Socket->ReadString(19); //Dla zdarzenia Execute

...trzeba podać liczbę znaków, które chcemy wyciągnąć z bufora. Możliwe, że liczba znaków będzie się zmieniać, tak więc jakiej funkcji użyć, aby wyciągnąć wszystkie znaki z bufora?
3. A teraz z innej beczki - korzystanie z protokołu UDP. Wysyłanie się powiodło, jednak mam problem z odczytem. Mianowicie UDPServer ma ustawiony ThreadedEvent na true, ale funkcja ONUDPRead raz działa, a raz nie działa. Tak na zmianę. Nie mam pojęcia co zrobić, aby za każdym razem pobierała znaki ze strumienia.
Kod: Zaznacz cały
void __fastcall TForm2::Server_UDPUDPRead(TIdUDPListenerThread *AThread, TBytes AData,
        TIdSocketHandle *ABinding)
{
   TIdBytes buf;
   TIdPort port;
   String IP;
   buf.Length = 1200;
   String count = Server_UDP->ReceiveBuffer(buf,IP,port,IdTimeoutDefault);
   Edit3->Text = count;
} //Wszystko robione na sucho, więc niektóre zmienne są stałe

4. A teraz to w ogóle odbiegnę od tematu. Chciałbym się nauczyć obsługi tego środowiska. Niestety, IDE nie należy do najsławniejszych, więc informacji na jego temat w internecie jest mało, tym bardziej w języku polskim.
Nie miałem wyboru - wziąłem się za dokumentację. Niestety, jak to dokumentacja, wszystko było opisane na sucho, po jednym, dwóch zdaniach. Mimo tego, że wiem za co odpowiedzialna jest niby ta funkcja, to nie wiem jak ją wykorzystać w kodzie, co trzeba zrobić, aby zamierzone działanie programu się powiodło i jakich wszystkie funkcje są do tego niezbędne. Jestem pełen podziwu do waszych umiejętności programistycznych, a w szczególności Barona. Skąd wy bierzecie taką wiedzę? Macie na to jakiś sposób?

Co do kodu proszę o łopatologiczne wytłumaczenie i najlepiej ze wstawkami kodu (zaznaczam, że nie jestem z tych ludzi, którzy oczekują gotowca. Ale jeśli macie chwilę czasu - nie pogardzę).
A teraz kodzik dla klienta:
http://wklej.org/id/533616/

A teraz chyba najważniejsze - instrukcja kolegi dot. danych wysyłanych i oczekiwanych przez serwer (mam nadzieję, że się nie obrazi, jeśli to upublicznię):
http://wklej.org/id/533618/

Z góry dziękuję.
'Jestem laikiem - ale chciałbym się czegoś nauczyć :P'
Avatar użytkownika
gmp13
Bladawiec
Bladawiec
 
Posty: 2
Dołączył(a): piątek, 27 sierpnia 2010, 10:50
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP Home Edition
Kompilator: C++ Builder 2009
Gadu Gadu: 8529114
    Windows XPOpera

Re: Obsługa protokołu TCP i UDP - INDY

Nowy postprzez Cyfrowy Baron » niedziela, 22 maja 2011, 20:33

gmp13 napisał(a):2. Przy odbieraniu komunikatów z "programu-serwera" za pomocą funkcji Read...
Kod: Zaznacz cały
UnicodeString komunikat = AContext->Connection->Socket->ReadString(19); //Dla zdarzenia Execute


KOD cpp:     UKRYJ  
ReadStrings(TStrings *ADest, int AReadLinesCount, TEncoding *AEncoding)


ADest - lista do której zostanie zapisany wynik pobrania
AReadLinesCount - oczekiwana liczba linii tekstu
AEncoding - sposób kodowania tekstu - można pominąć

KOD cpp:     UKRYJ  
TStringList *SList = new TStringList();

void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
 TEncoding *Encode;

 AContext->Connection->Socket->ReadStrings(SList, 10, Encode->UTF8);
}
Inne funkcje Read...

read.png
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Obsługa protokołu TCP i UDP - INDY

Nowy postprzez gmp13 » poniedziałek, 23 maja 2011, 16:42

Pięknie dziękuję :D
Najbardziej zależałoby mi na rozwiazaniu problemu numer 1. Jeśliby ktoś miał pomysł, jak to rozgryźć - proszę o informację.

EDIT
Zdobyłem parę informacji na temat wysyłania danych. Działający kod z użyciem innych klas niż INDY dla klienta wygląda tak:
Kod: Zaznacz cały
public void wyslijIleKartWymienic()
{
strumienWysylanie = klient.GetStream();
int doWymiany = listaKart.Count;
string daneWyslane = doWymiany.ToString();
byte[] bufforDane = Encoding.ASCII.GetBytes(daneWyslane);
strumienWysylanie.Write(bufforDane, 0, bufforDane.Length);
}


EDIT 2
Skleciłem coś takiego:
Kod: Zaznacz cały
void __fastcall TForm3::Button2Click(TObject *Sender)
{
TEncoding* Encode;
UnicodeString Message;
UnicodeString tekst = Edit1->Text;
TByteDynArray bity = Encode->ASCII->GetBytes(tekst);
TCPClient->Socket->Write(bity, 0, bity.Length);
for (int i = 0; i < bity.Length; i++) {
   Message = Message + " " + bity[i];
}
Memo1->Lines->Add("Wysłano: " + Message + " || Bajtów: " + (int) bity.Length);
}
//---------------------------------------------------------------------------


Niestety, nie chce działać :(
Avatar użytkownika
gmp13
Bladawiec
Bladawiec
 
Posty: 2
Dołączył(a): piątek, 27 sierpnia 2010, 10:50
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP Home Edition
Kompilator: C++ Builder 2009
Gadu Gadu: 8529114
    Windows XPOpera


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje sieciowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości