[ itf @ 31.10.2009. 15:14 ] @
Imam jedan čudan problem pri UDP klijent-server komunikaciji (Indy 9). Code je sljedeći:

Code:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int n = 5;

    C1->SendBuffer(&n, sizeof(int));
    C1->ReceiveBuffer(&n, sizeof(int));
    Label1->Caption = n;
}
void __fastcall TForm1::S1UDPRead(TObject *Sender, TStream *AData,
      TIdSocketHandle *ABinding)
{
    int n;
    AData->ReadBuffer(&n, sizeof(int));
    n++;
    ABinding->SendTo(ABinding->IP, ABinding->Port, &n, sizeof(n)); // ne radi...
    //AData->WriteBuffer(&n, sizeof(int)); // niti ovo...
    //AData->Write(&n, sizeof(int));  // niti ovo..
}


Pokušavam iz UDP klijenta serveru poslati br 5, a da mi server vrati taj isti broj uvećan za 1. Međutim, iz servera se niti na jedan od ova tri načina poruka neće poslati nazad klijentu. Kao da nisam ništa niti napisao. U čemu griješim? Naravno, portovi su identični na klijent i server strani i host je ispravno definiran.

Također, imam desetak UDP servera u labosu i trebao bih pritiskom na gumb znati koji od njih je upaljen a koji ne. Zapravo, to sam mislio napraviti broadcastom, ali ta funkcija kao prvi parametar ima AnsiString, a ja bi trebao serverima poslati ID zahtjeva. Npr. preko broadcasta bi htio svima u mreži poslati br. 50, a svi koji su to primili da mi taj isti broj vrate nazad. Ideje? Inače, ping ne mogu koristiti zbog nekih drugih stvari..
[ Mihajlo Cvetanović @ 31.10.2009. 18:08 ] @
Prvo moraš da pronađeš gde je problem. Instaliraj Wireshark i utvrdi da li paket uopšte dođe da servera, i da li uopšte izađe iz klijenta.
[ itf @ 31.10.2009. 18:10 ] @
Paket stigne na server. Problem je što server ne šalje odgovor.
[ Mihajlo Cvetanović @ 01.11.2009. 09:08 ] @
Da li ti server osluškuje? Da li vidiš svoj port kad u konzoli izvršiš "netstat -a -p udp"? Da li možeš da debaguješ server, da li se uopšte izvršava kod u funkciji TForm1::S1UDPRead?
[ itf @ 01.11.2009. 09:30 ] @
Vec sam gore napisao da na server stigne paket i to nije problem, vec od servera prema klijentu ne radi.
[ Mihajlo Cvetanović @ 01.11.2009. 10:07 ] @
Da li postoji neka povratna vrednost funkcije, koja bi ti rekla u čemu je greška? Da li možeš debagovanjem da dođeš do SDK funkcije koja zaista šalje paket sa servera? Da li paket izađe iz servera? Uzgred, jesu li klijent i server na istoj mašini? Ako jesu onda Wireshark ne može da ti pomogne tako lako.
[ markom @ 01.11.2009. 10:36 ] @
Glupo pitanje. Da li ti je ugašen firewall na klijentima i serveru?
[ X Files @ 01.11.2009. 20:59 ] @
Nisam nikada radio sa Indy UDP, ali na osnovu neke logike, ovda dva poziva:
AData->WriteBuffer(&n, sizeof(int)); // niti ovo...
AData->Write(&n, sizeof(int)); // niti ovo..
... ne vracaju stream NAZAD (klijentu), sto je ocigledno zelja, vec samom sebi u AData.

Mislim da je slicno i za ovo:
ABinding->SendTo(ABinding->IP, ABinding->Port, &n, sizeof(n)); // ne radi...
... tj, da se salju podaci rekurzivno samom serveru, koji to (na osnovu koda) opet prima/salje/prima/salje.

Moguce je da treba pokusati sa:
PeerIP i PeerPort, i videti sta sa BroadCasting-om u smislu True/False.



[Ovu poruku je menjao X Files dana 02.11.2009. u 10:06 GMT+1]
[ itf @ 02.11.2009. 09:06 ] @
Ne vidim smisao u tome da server razgovara sa samim sobom. A po ovom primjeru iz Delphija ABinding ima informaciju o pošiljatelju.

Code:
procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
  DataStringStream: TStringStream;
  s: String;
begin
  DataStringStream := TStringStream.Create('');
  try
    DataStringStream.CopyFrom(AData, AData.Size);
    UDPMemo.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));
    s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"';
    ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
  finally
    DataStringStream.Free;
  end;
end;


[ X Files @ 02.11.2009. 09:23 ] @
Citat:

Ne vidim smisao u tome da server razgovara sa samim sobom.

Ne radi se o smislu (verovatno ga i nema), nego metoda za slanje streama SendTo (koja je unutar Server OnRead), prosledjuje stream po IP i Portu, a ti podaci su bas oni koje ima taj server, pa ga on i prima, jer ima implementiran OnRead, koji se igrom slucaja slaze po velicini i tipu onoga sto se prima.

Drugim recima, ABinding ima: IP, PeerIP, Port i PeerPort. E sad, treba videti gde i sta treba da se podesi da bi se gadjao klijent koji je poslao stream. Najbolje stavi neki Memo i ispisi vrednosti svih ovih parametara na prijemu. Po meni treba ona varijanta sa Peer.

Citat:

A po ovom primjeru iz Delphija ABinding ima informaciju o pošiljatelju.

Naravno da ima te informacije, ali to nisu IP i Port, pretpostavljam da treba PeerIP i PeerPort, bas kao sto je u primeru.
[ itf @ 02.11.2009. 09:28 ] @
Da. U tome je stvar. Nisam ni primjetio da sam umjesto PeerIP koristio IP. Port je isti na obje strane. Znači, rješenje je:

ABinding->SendTo(ABinding->PeerIP, ABinding->PeerPort, &n, sizeof(int));

Zahvaljujem.

EDIT:
Inače, ima tko kakav primjer za slanje broadcasta?