[Delphi] Socket ontvangen

Pagina: 1
Acties:

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Ik word er gek van. Ik heb een server draaien op een Linux machine ergens waarmee je dan via TCP/IP kan communiceren.
Als ik bijvoorbeeld 'SKILLS' stuur krijg ik als antwoord
code:
1
2
OK
0

als ik bijvoorbeeld '.' stuur krijg ik (omdat ie niet kent natuurlijk).
code:
1
2
3
ERR
2
Command not recognized

Ik heb nu een leuk Delphi Programma gemaakt waarmee je dan 'SKILLS' zou kunnen sturen en het ontvangen text ergens in een MEMO bijvoorbeeld zou kunnen zien.
Hiervoor heb ik een ClientSocket op de form gedropped maar hij wil niet echt. Versturen lukt, da's geen probleem. Ontvangen wil niet. Op de OnRead event reageert ie niet, dus ik dacht ik doe het wel in een functie. Zo bijvoorbeeld:
code:
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
with ClientSocket do
    begin
    Host := pc301g.liacs.nl;
    ClientType := ctBlocking;
    Port := 2096;

    try
      Open;
      {send query}
      s := 'SKILLS'+#13#10;
      intReturnCode := Socket.SendBuf(Pointer(s)^, Length(s));

      if intReturnCode > 0 then
      begin
        {receive the answer}
        { iterate until no more data }
        while (intReturnCode > 0) do
        begin
        { clear buffer before each iteration }
        FillChar(szBuffer, SizeOf(szBuffer), 0);

        { try to receive some data }
        intReturnCode := Socket.ReceiveBuf(szBuffer, SizeOf(szBuffer));

        { if received a some data, then add this data to the result string }
        if intReturnCode > 0 then
          FileOut.Write(szBuffer, intReturnCode);
        end
      end
      else
        MessageDlg('No answer from server', mtError, [mbOk], 0);

      Close;
    except
      MessageDlg('No connection', mtError, [mbOk], 0);
    end;
    end;

Hij leest het mooi in, maar nadat ie de '0' heeft ingelezen blijft ie hangen bij ReceiveBuf() en doet niks meer. Toen dacht ik omdat dat ding ctblocking is, ik TWinSocketStream moet gebruiken (staat in Help).
Bij readen heb ik dan
code:
1
intReturnCode := Sock.Read(szBuffer, SizeOf(szBuffer));

gedaan. Die doet het ook goed. Maar als ik voor de tweede keer een commando intyp, dan zit zijn antwoord (eerste regel, of als ik het per character inlees, het eerste character) al in de buffer voordat ik het lees, dus al voor FillChar want die reset het weer. :?

Ik snap er echt geen drol meer van.
Kan iemand me helpen? Als je het zelf wil proberen: pc301g.liacs.nl port 2096. Met telnet enzo doet ie het wel.

Edit. Die Sock.Read is dus van type
code:
1
Sock: TWinSocketStream

en heb ik aangemaakt met
code:
1
Sock := TWinSocketStream.Create(ClientSocket1.Socket, 1000);

. Ook een WaitData helpt niet


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • Kool
  • Registratie: September 1999
  • Niet online
Gebruik gewoon de SendText method en doe geen #13#10 aan het eind. Je bent in Delphi bezig en niet in C hoor. Dan moet het gewoon werken. :)

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Op donderdag 27 juni 2002 20:27 schreef Kool het volgende:
Gebruik gewoon de SendText method en doe geen #13#10 aan het eind. Je bent in Delphi bezig en niet in C hoor. Dan moet het gewoon werken. :)
Maar da's op zich niet het probleem. Het probleem zit het met het ontvangen.


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • Kool
  • Registratie: September 1999
  • Niet online
Welke componenten gebruik je nou, TClientSocket of TCPClient?

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Op donderdag 27 juni 2002 20:40 schreef Kool het volgende:
Welke componenten gebruik je nou, TClientSocket of TCPClient?
TClientSocket.

Ik ben wel achter het probleem denk ik. Het server is ctBlocking, dus op Events enzo reageert ie niet. Ik wil dan de output lezen tot er niks meer is. Maar nadat ie de laatste gelezen heeft blijft Socket.ReceiveText() op de nieuwe input wachten (die er natuurlijk niet komt). Maar hoe weet ik nou dat de transmissie ten einde is?

Dus ReceiveText of andere werken alleen op events. Die is er niet, dus ik zou TWinSocketStream moeten gebruiken. Maar hiermee is het probleem dus dat ie ook op de een of andere manier bij de volgende response al iets daarvan in de buffer heeft.


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • Kool
  • Registratie: September 1999
  • Niet online
Je hebt dan toch de TServerSocket.OnClientRead event :?
Daarin Socket.ReceiveText. Je moet ze dan wel op nonblocking laten staan.

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Op donderdag 27 juni 2002 20:46 schreef Kool het volgende:
Je hebt dan toch de TServerSocket.OnClientRead event :?
Daarin Socket.ReceiveText. Je moet ze dan wel op nonblocking laten staan.
Die Server zit ergens op Linux, daar kan ik dus niks aan veranderen. Ik wil gewoon op het scherm zetten wat de server mij antwoordt. En aangezien die blocking is, kan ik die event niet gebruiken.


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


  • Kool
  • Registratie: September 1999
  • Niet online
Dan kun je het beste het Indy TCP component nemen.

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Op donderdag 27 juni 2002 20:55 schreef Kool het volgende:
Dan kun je het beste het Indy TCP component nemen.
Hey, Dank je wel!!
Ik heb nu dit gedaan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  IdTCPClient1.Connect();
  if IdTCPClient1.Connected then
  begin
    s := '.';
    IdTCPClient1.Writeln(s);
    repeat
    begin
    s := IdTCPClient1.ReadLn(EOL,2000);
    end;
    until s = '';
  end;
  begin
    s := 'dd';
    IdTCPClient1.Writeln(s);
    repeat
    begin
    s := IdTCPClient1.ReadLn(EOL,2000);
    end;
    until s = '';
  end;
  IdTCPClient1.Disconnect();

Bijvoorbeeld. Een beetje erg lelijk nu, maar het gaat om dat ie het doet. Ik krijg nog wel een timeout als ie de laatse character ingelezen heeft (dus als de server "OK"..enter.."0" teruggeeft, leest ie mooi "OK" in en daarna "0" en daarna hangt ie die 2 seconden (zal ik wel lager zetten)), maar hij doet het. Ook bij een tweede poging geeft ie mooi alles terug :)

Wie had gedacht dat het zo stom is dat de ene het niet doet en de andere wel :'(


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge

Pagina: 1