Seite 1 von 5

OpenNetworkConnectionEx() mit Timeout

Verfasst: 15.10.2005 20:41
von MLK
es war nicht einfach, aber hat geklappt. endlich keine hängenden netzwerkprogramme mehr.

Code: Alles auswählen

Procedure OpenNetworkConnectionEx(ServerName$, Port.l, TimeOut.l)
  !Conn equ Esp+12
  !Wsa  equ Esp+28
  !Tout equ Esp+428
  !Wait equ Esp+436
  !Sock equ Esp+444
  
  WsaData.WSADATA
  Connection.SOCKADDR_IN
  TimeOuts.TIMEVAL
  WaitSock.ULARGE_INTEGER
  Sock.l
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  !if ~ defined _gethostbyname@4 | defined @f
  !extrn _gethostbyname@4 
  !@@:
  !end if
  ;
  !if ~ defined _WSAStartup@8 | defined @f
  !extrn _WSAStartup@8
  !@@:
  !end if
  ;
  !if ~ defined _socket@12 | defined @f
  !extrn _socket@12
  !@@:
  !end if
  ;
  !if ~ defined _htons@4 | defined @f
  !extrn _htons@4
  !@@:
  !end if
  ;
  !if ~ defined _ioctlsocket@12 | defined @f
  !extrn _ioctlsocket@12
  !@@:
  !end if
  ;
  !if ~ defined _connect@12 | defined @f
  !extrn _connect@12
  !@@:
  !end if
  ;
  !if ~ defined _select@20 | defined @f
  !extrn _select@20
  !@@:
  !end if
  ;
  !if ~ defined _closesocket@4 | defined @f
  !extrn _closesocket@4
  !@@:
  !end if
  ;
  !if ~ defined _WSACleanup@0 | defined @f
  !extrn _WSACleanup@0
  !@@:
  !end if
  
  ;;;;;;;;;;;;;;;;;;
  !MOV    Eax, [Esp]
  !OR     Eax, Eax
  !JZ     @f
  !PUSH   Eax
  !CALL   _gethostbyname@4 
  !OR     Eax, Eax
  !JZ     @f
  !MOVSX  Ebx, word [Eax+8]
  !CMP    Ebx, 2
  !JNE    @f
  !MOV    Ecx, [Eax+12]
  !MOV    Ecx, [Ecx]
  !MOV    Ecx, [Ecx]  
  !MOV    [Conn+4], Ecx  
  !LEA    Eax, [Wsa]
  !PUSH   Eax
  !PUSH   $0002
  !CALL   _WSAStartup@8
  !OR     Eax, Eax
  !JNZ    @f  
  !CMP    byte [Wsa], 2
  !JL     @f
  !PUSH   6
  !PUSH   1
  !PUSH   2
  !CALL   _socket@12
  !CMP    Eax, -1
  !JE     @f  
  !MOV    [Sock], Eax
  !MOV    word [Conn], 2
  !PUSH   dword [Esp+4]
  !CALL   _htons@4
  !MOV    word [Conn+2], ax
  !MOV    Eax, dword [Esp+8]
  !MOV    dword [Tout], Eax
  !MOV    dword [Wait], 1
  !MOV    Eax, dword [Sock]
  !MOV    dword [Wait+4], Eax
  !LEA    Eax, [Wait]
  !PUSH   Eax
  !PUSH   -2147195266
  !PUSH   dword [Sock+8]
  !CALL   _ioctlsocket@12
  !PUSH   dword 16
  !LEA    Eax, [Conn+4]
  !PUSH   Eax
  !PUSH   dword [Sock+8]
  !CALL   _connect@12
  !LEA    Eax, [Tout]
  !PUSH   Eax
  !PUSH   0
  !LEA    Eax, [Wait+8]
  !PUSH   Eax
  !PUSH   0
  !PUSH   0
  !CALL   _select@20
  !CMP    Eax, 0
  !JNA    @f
  !LEA    Eax, [Tout+4]
  !PUSH   Eax
  !PUSH   -2147195266
  !PUSH   dword [Sock+8]
  !CALL   _ioctlsocket@12
  !CALL   _WSACleanup@0
  !MOV    Eax, [Sock]
  ProcedureReturn  
  !@@:
  !CMP    dword [Sock], -1
  !JNE    @f
  !PUSH   dword [Sock]
  !CALL   _closesocket@4  
  !@@:
  !CMP    byte [Wsa], 0
  !JE     @f
  !CALL   _WSACleanup@0
  !@@:
  
  ;;;;;;;;;;;;;
  !Restore Conn
  !Restore Wsa
  !Restore Tout
  !Restore Wait
  !Restore Sock
EndProcedure


InitNetwork()

Host$ = "www.purearea.net"

ServerID = OpenNetworkConnectionEx(Host$, 80, 1)
If ServerID = 0
  MessageRequester("", "Timeout")
Else
  If SendNetworkString(ServerID, "GET / HTTP/1.1" + #CRLF$ + "Host: " + Host$ + #CRLF$ + #CRLF$)
    Response$   = Space($FFF)
    ResponseLen = Len(Response$)
    Repeat
      inLen = ReceiveNetworkData(ServerID, @Response$ + Pos, ResponseLen - pos)
      Pos + inLen
    Until inLen = 0 Or Pos = ResponseLen
    MessageRequester("", Response$)
  EndIf
  CloseNetworkConnection(ServerID)
EndIf

und noch ein kleines nebenprodukt:

Code: Alles auswählen

Procedure$ GetHostIP(Host$)
  !if ~ defined _inet_ntoa@4 | defined @f
  !extrn _inet_ntoa@4
  !@@:
  !end if
  !if ~ defined _gethostbyname@4 | defined @f
  !extrn _gethostbyname@4 
  !@@:
  !end if
  
  ;;;;;;;;;;;;;;;;;;
  !MOV    Eax, [Esp]
  !OR     Eax, Eax
  !JZ     @f
  !PUSH   Eax
  !CALL   _gethostbyname@4 
  !OR     Eax, Eax
  !JZ     @f
  !MOVSX  Ebx, word [Eax+8]
  !CMP    Ebx, 2
  !JNE    @f
  !MOV    Ecx, [Eax+12]
  !MOV    Ecx, [Ecx]
  !MOV    Ecx, [Ecx]
  !PUSH   Ecx
  !CALL   _inet_ntoa@4
  !MOV    Edx, Eax
  !PUSH   dword [PB_StringBase]
  !CALL   SYS_CopyString
  !POP    Eax
  ProcedureReturn
  !@@:
EndProcedure

InitNetwork()
MessageRequester("", GetHostIP("www.purearea.net"))

falls jemand eine idee hat, wie man den nötigen platz auf dem stack reservieren kann, ohne die hässlichen zeilen 8-11 (1. code), dann raus mit der sprache. und wenn es hier gar jemanden gibt, der sich mit asm/pb-asm-output/libs etc. auskennt und nichts dagegen hätte sich mal gelegentlich von mir ausfragen zu lassen -> PN


..und zögert nicht mir zu huldigen

Verfasst: 15.10.2005 21:00
von nicolaus
:allright: gefällt mir sehr gut!
Schicks gleich weiter an Fred :mrgreen:

Verfasst: 29.10.2005 14:45
von DataMiner
Ähm, wenn ich in jaPBe folgende Fehlermeldung erhalte:
jePBe - Assembler Fehler

PureBasic.asm [224]:
MOV dword[Wait], 1
error: reserved word used as symbol.
Bedeutet das was?

EDIT: OK, habs selbst herausgefunden. Habe "Wait" durch "Waits" ersetzt, jetzt funzt es.
SUPER!

Verfasst: 29.10.2005 15:04
von ts-soft
>> Bedeutet das was?
Ja, Du hast InlineASM angeschaltet gehabt in den CompilerOptionen. Dies ist ja extra abschaltbar, um Konflikte mit ASM-Befehlen zu vermeiden. Der obige Code verwendet ja DirectASM, also kein InlineASM, so das ein anschalten nicht erforderlich ist.

Verfasst: 11.07.2007 22:40
von N00B
DataMiner hat geschrieben:Ähm, wenn ich in jaPBe folgende Fehlermeldung erhalte:
jePBe - Assembler Fehler

PureBasic.asm [224]:
MOV dword[Wait], 1
error: reserved word used as symbol.
Bedeutet das was?

EDIT: OK, habs selbst herausgefunden. Habe "Wait" durch "Waits" ersetzt, jetzt funzt es.
SUPER!
Und welches davon hast ersetzt ? :freak:

Ich hab alle Wait durch Waits ersetzt, und dann kamm leider schon die Nächste Fehlermeldung(Inline ASM ist aus)

@MLK

Wie nutzt ich das gute Stück Arbeit das die für uns gemacht hast ?

hier das Zeuch eintragen ?
:freak:

Code: Alles auswählen

  WsaData.WSADATA
  Connection.SOCKADDR_IN
  TimeOuts.TIMEVAL
  WaitSock.ULARGE_INTEGER
  Sock.l
obwohl äh blöd gefragt.

Besser ist, wo muss ich da selber noch was reinsetzten ausser beim Host String ?

Nur den Timeout noch festlegen ?(wenn ja, wo ?) oder noch irgendwie da bei WaitSock.ULARGE_INTEGER was eingeben ?

Verfasst: 11.07.2007 22:45
von ts-soft
N000B hat geschrieben:
obwohl äh blöd gefragt.

Besser ist, wo muss ich da selber noch was reinsetzten ausser beim Host String ?

Nur den Timeout noch festlegen ?(wenn ja, wo ?) oder noch irgendwie da bei WaitSock.ULARGE_INTEGER was eingeben ?

Code: Alles auswählen

Procedure OpenNetworkConnectionEx(ServerName$, Port.l, TimeOut.l) 
Ich würde mal raten, der dritte Parameter bestimmt das TimeOut :wink:

PS: Der Thread hat schon 2 Jahre auf dem Buckel, erstmal testen ob das für
die aktuelle PB Version überhaupt noch geht!

Verfasst: 11.07.2007 22:59
von N00B
OMG bin bin blöd, wie peinlich voll übersehen :oops:

Danke für die Rasche Hilfe :allright:

Was ich mich noch Frage, fast ganz unten im Code (nach der ASM und WinApi Sache)

Kommt ja noch mal

Code: Alles auswählen

InitNetwork()
            
            Host$ = "www.purearea.net"
            
            ServerID = OpenNetworkConnectionEx(Host$, 80, 1)
            If ServerID = 0
              MessageRequester("", "Timeout")
            Else
              CloseNetworkConnection(ServerID)
              
            EndIf 
vor.

Jetzt verstehe ich leider nicht warum, das nach der Prozedure noch mal vorkommt, und vor allem auch nicht warum bei ServerID = 0 die Meldung "Timeout" ist, und nicht einfach nur "Open Connection Failed" oder so was in der Richtung.

:freak:

Ok im ersten Moment hört sich das nur nach falscher String angabe an, aber es besteht ja ein wesentlicher Unterschied zwischen überhaupt keiner Verbindung und einer aufgebauten die einfach ein Zeit Pensum überschritte hat.


Der Thread ist schon so alt
:shock: ? Neiiiiiiiiiiiiiiiin :( seit nem halben Jahr hänge ich schon an meinem Programm, und hatte endlich auf eine einfach Lösung gehofft :cry: hab PB 4.02 und leider muss ich jedesmal meine Firewall abschalten damit nicht auf der Stelle eine blabla in Speicheradresse bla Zugriffsverletzung bla Meldung kommt(falls ich ne exe generieren will) :oops: und der Debugger hängt dann schon ind er Ersten Zeile mit na Speicheradressierungs Fehlermeldung.

Desshalb kann ich leider nicht so lange dran rumtesten wie ich gerne würde, hab zu viel Angst vor DoS Attacken, Port Scans usw.

Verfasst: 11.07.2007 23:06
von ts-soft
>> hab zu viel Angst vor DoS Attacken, Port Scans usw.
Ich weiß ja nicht welche Firewall Du verwendest? Ich nutze z.B. ZoneAlarm
mit AntiVirus und habe die von PB generierten Exen als "häufige Änderungen"
mit Interneterlaubnis ausgestattet.

Vor DoS Attacken schützt ja auch eine evtl. HardwareFirewall im Router.

Verfasst: 11.07.2007 23:19
von N00B
Hab leider keine Hardwarefirewall :freak:

Und meine derzeitige Firewall (Sygate 5.6 Pro Debug) hat leider nicht diese Option das zu häufig wechselnde Anwendungen erlaubt werden.

Normalerweise fragt meine Firewall ja noch mal nach, wenn ne Datei geändert wurde, nur bei dem Timeout Code leider nicht :-(

Hatte gestern ewig am Code rumprobiert (mit aktivierter Firewall) damit keine Fehlermeldung mehr kamm, nachdem ich das irgendwie hinbekommen hatte, kamm immer wieder diese Speicherfehler Meldung, hab an den ASM Befehlen nichts verändert, glaub nur das wait überall durch waits ersetzt

ab hier (Zeile 14 oder 15)

Code: Alles auswählen

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  !if ~ defined _gethostbyname@4 | defined @f
Dann kamm ne andere Meldung, irgendwas mit "Symbols in blab not found" oder so, dann hab ich wieder rumgspielt, und dann kamm keine Fehlermeldung mehr.

Aber leider das, was mir bei Opennetwork Connection schon immer passiert ist, seit PB 4.

Diese Speicherfehlermeldung ist 100% auf meine Firewall zurückzuführen ist :-(

Verfasst: 12.07.2007 17:02
von dysti
Hey,
im ersten Beispiel bekomme ich ein "Invalid Memory Access"
und im zweiten Beispiel in der Zeile "CALL SYS_CopyString" ein "undefined symbol".
Wie bekomme ich die Errors weg. Von ASM keinen Schimmer.
(Pb 4.02)