Delphis tcp ip-s kliens hiba csak neten

Delphis tcp ip-s kliens hiba csak neten
2006-10-01T18:33:02+02:00
2006-10-03T16:24:27+02:00
2022-11-01T16:42:03+01:00
lamer@localhost
Sziasztok van egy furcsa problémám. Írtam egy klienst és egy szervert is a delphi komponenseivel. A kommunkáció a kliensek és a szerver között tökéletes belső hálózaton, ám ha neten kerülnek kapcsolatba a szerver nem hajlandó csatlakoztatni egy klienset sem.
Mutasd a teljes hozzászólást!
A hibaüzenet azt jelenti, hogy nem-blokkolódó socketen akarsz olyan műveletet végrehajtani, amihez blokkolni kéne a socketet.
Egészen pontosan melyik sornál adja a hibát?
Meg kéne nézni, hogy az adott függvényhívást hogy kell helyettesíteni non-blocking socketet használatánál.
Megjegyzem, hogy a blocking és a non-blocking socketek programozásának filizófiája picit eltér.
Pl. az Accept() nem hajtódik végre rögtön, hanem csak elindít a rendszerben egy "accept"-et (jobban nem tudom megfogalmazni, bocsi), és rögtön visszatér.
A program windows-üzeneteken, vagy esetleg callbackon keresztül értesülhet arról, hogy az Accept() megtörtént-e, sikeres lett-e, stb.
Ugyan ez a helyzet a Read(), Write(), ReceiveBuf(), stb. fgv-kkel is.
Ahogy a kódodat elnézem, neked inkább blocking socketeket kéne használnod!
A blokkolódó socketeknél a fennt említett függvényhívások nem térnek vissza addig, amíg a művelet végre nem hajtódott (vagy éppen nem sikerült végrehajtani) - ezért is nevezik blocking-socketnek, mert a socket műveletek alatt blokkolja a program futását.
A kódodat csak felületesen futottam át, de fontos, hogy accept(), receive(), write() és minden más után _csinálj hibakezelést_!
Még egy tanács, de ez szubjektív: én a helyedben hanyagolnám a delphi socket-komponenseit, inkább használj natív WinSock hívásokat (nem bonyolult, sőt szvsz. átláthatóbb lesz a dolog, mert mindig tudod, hogy mi történik, nem rejtik el a dolgokat a komponensek)!
Kiindulásképp: http://people.inf.elte.hu/triasz/progi/bgnet.html
Ezt mindenképp tanácsos elolvasnod, akkor is, ha nem térsz át natív Winsock-ra!

Üdv: psc
Mutasd a teljes hozzászólást!

  • Leírom az idevágó kódot:

    -kliens csatlakozása:


    procedure Tindit.Button2Click(Sender: TObject); var s: array[0..3] of char; begin if Not Connected then begin tcpclient1.RemoteHost :=edit2.Text; tcpclient1.LocalHost := TcpClient1.LocalHostAddr; tcpclient1.LocalPort := port.text; Application.ProcessMessages; button2.Caption:='Bontás'; tcpclient1.Open; s:=CMD_VERZIO; tcpclient1.SendBuf(s, 4); tcpclient1.Sendln(VERZIO); s:=CMD_JELSZO; tcpclient1.SendBuf(s, 4); tcpclient1.Sendln(jelszo.Text); tcpclient1.Sendln(nev.Text); timer1.Enabled:=true; end else begin tcpclient1.Close; tcpclient1.Disconnect; button2.Caption := 'Kapcsolódás'; Connected := false; timer1.Enabled:=false; end; end;

    -Amikor a szerver fogadja a klienst és lellenőrzi a verzióját:


    procedure klienscsatl; var hiba:boolean; begin hiba:=false; Setlength(Clients, length(Clients)+1); Clients[high(Clients)] := Tkliens.Create(main); Clients[high(Clients)].jatekosazon:=high(Clients); main.TcpServer1.Accept(Tcustomipclient(Clients[high(Clients)])); Setlength(jatek.jatekosok, length(jatek.jatekosok)+1); jatek.jatekosok[high(jatek.jatekosok)]:= Tjatekos.Create; jatek.jatekosok[high(jatek.jatekosok)].azon:=high(jatek.jatekosok); if inttostr(length(Clients))>inttostr(jatek.maxjatekos) then begin main.klienski(high(Clients),'A játékosok elérték a maximális számot!'); hiba:=true; end; if jatek.futo and (not hiba) then begin main.klienski(high(Clients),'A játék már elindult!'); hiba:=true; end; if not hiba then begin end; end; for I := 0 to high(Clients) do begin if assigned(Clients[I]) then if not Clients[I].Active then lista.Memo1.Lines.Add('Client '+inttostr(I)+' Not Active.') else begin Clients[I].Select(@R,@W,@E); lista.Memo1.Lines.Add('Client ('+inttostr(I)+'): Read: '+booltostr(R)+ ' Write: '+booltostr(W)+ ' Exception: '+booltostr(E)); If R then begin if Clients[I].ReceiveBuf(S, 4) <= 0 then begin klienski(I,''); goto Ide; end else begin if s=CMD_VERZIO then begin Txt := Clients[I].Receiveln; if Txt<>VERZIO then begin klienski(I,'Verzió eltérés'); end; end; end;

    Persze sok mást is kommunkiálnak de, most kitettem netre és behalt a szerver a következő hibaüzenetet adja:


    procedure Tkliens.hiba(Sender: TObject; SocketError: Integer); Var S: string; begin Case SocketError of EWOULDBLOCK: S := 'Would hang the system if this command was executed.'; !!!! EZT ADJA HIBAÜZENETNEK DE CSAK NETRŐL EINPROGRESS: S := 'In Progress.'; EALREADY: S := 'Already doing this'; ENOTSOCK: S := 'Not a socket'; EMSGSIZE: S := 'Something about the message size. :)'; EPROTOTYPE: S := 'Protocol Type'; EADDRINUSE: S := 'Address in use.'; EADDRNOTAVAIL: S := 'Address not avaliable'; ENETDOWN: S := 'The system is down yo.'; ECONNRESET: S := 'Connection Reset by host.'; EHOSTUNREACH: S := 'Host unreachable.'; EHOSTDOWN: S := 'Host Down'; WSAECONNREFUSED: S := 'Connection Refused.'; WSAECONNABORTED: S := 'Connection Aborted.'; else S := 'Unknown ('+inttostr(SocketError)+')'; end; //main.klienski(jatekosazon,''); lista.ListBox1.Items.Insert(0,'Socket Error: '+S); end;

    Ha valaki segítene azt úgy megköszönném, hogy csak na
    Mutasd a teljes hozzászólást!
  • A jelenséggel én is találkoztam (ne haragudj, most nincs időm átnézni a kódod, csak tippeket adok).
    1. tűzfal blokkol
    2. router
    3. más is ül a porton?
    Mutasd a teljes hozzászólást!
  • A hibaüzenet azt jelenti, hogy nem-blokkolódó socketen akarsz olyan műveletet végrehajtani, amihez blokkolni kéne a socketet.
    Egészen pontosan melyik sornál adja a hibát?
    Meg kéne nézni, hogy az adott függvényhívást hogy kell helyettesíteni non-blocking socketet használatánál.
    Megjegyzem, hogy a blocking és a non-blocking socketek programozásának filizófiája picit eltér.
    Pl. az Accept() nem hajtódik végre rögtön, hanem csak elindít a rendszerben egy "accept"-et (jobban nem tudom megfogalmazni, bocsi), és rögtön visszatér.
    A program windows-üzeneteken, vagy esetleg callbackon keresztül értesülhet arról, hogy az Accept() megtörtént-e, sikeres lett-e, stb.
    Ugyan ez a helyzet a Read(), Write(), ReceiveBuf(), stb. fgv-kkel is.
    Ahogy a kódodat elnézem, neked inkább blocking socketeket kéne használnod!
    A blokkolódó socketeknél a fennt említett függvényhívások nem térnek vissza addig, amíg a művelet végre nem hajtódott (vagy éppen nem sikerült végrehajtani) - ezért is nevezik blocking-socketnek, mert a socket műveletek alatt blokkolja a program futását.
    A kódodat csak felületesen futottam át, de fontos, hogy accept(), receive(), write() és minden más után _csinálj hibakezelést_!
    Még egy tanács, de ez szubjektív: én a helyedben hanyagolnám a delphi socket-komponenseit, inkább használj natív WinSock hívásokat (nem bonyolult, sőt szvsz. átláthatóbb lesz a dolog, mert mindig tudod, hogy mi történik, nem rejtik el a dolgokat a komponensek)!
    Kiindulásképp: http://people.inf.elte.hu/triasz/progi/bgnet.html
    Ezt mindenképp tanácsos elolvasnod, akkor is, ha nem térsz át natív Winsock-ra!

    Üdv: psc
    Mutasd a teljes hozzászólást!
  • Igaz, tényleg blokkolni kell. Bár magamtól is rájöttem, igaz próbálgatásos módszerrel azért kösz a fáradságot. Amúgy elég gáznak tűnnek nekem is ezek a komponensek, csak a könyv azt sugalmazta, hogy a socketek programozása bonyolult. No mindegy megnézem a linket és mégegyszer kösz.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd