Seite 1 von 2

Computer und Port bereit ?

Verfasst: 08.03.2011 20:13
von Elektrolurch
Hallo

ich habe mal wieder, ein kleines Problem für die Menschheit, aber ein großes Problem für mich.

In meinem Programm spreche ich über Telnet einen Linux basierenden MP3Player an um ihn zu modifizieren.
Ich habe nur folgendes Problem wenn ich oder ein User vergessen, den Player oder den darauf laufenden Telnet Server einzuschalten, dann hängt mein Programm ca 45Sekunden und wartet auf eine Antwort.

Ich starte die Verbindung mit

Code: Alles auswählen

Verbindung = OpenNetworkConnection(IP_Adresse.s, 23)
Ich fange auch das Nullergebnis ab, aber es dauert halt ewig lange, was manche User zu den lustigsten Aktionen veranlaßt.
Kann man nicht mit einer Art kurzem Ping checken ob der PC antwortet?
Am besten gleich ob der Port aktiv ist?
Oder kann man den Timout verkürzen?

Ich hoffe ihr könnt mir helfen.

BYe André

Re: Computer und Port bereit ?

Verfasst: 08.03.2011 22:04
von HeX0R
Ich packe OpenNetworkConnection grundsätzlich in einen Thread (eben wegen den von dir geschilderten Problemen).
Das Hauptprogramm bleibt dann bedienbar und durch einen Cancel-Button wird der Thread einfach gekillt, wenn es zu lange dauert.
In dem Fall, wenn nichts anderes in dem Thread passiert, ist ein KillThread auch gar nicht so böse :mrgreen:

Davon abgesehen, würde aber in deinem Fall auch noch ein anpingen helfen.
Vorrausgesetzt der MP3Player reagiert darauf überhaupt.

Re: Computer und Port bereit ?

Verfasst: 09.03.2011 23:25
von Elektrolurch
Hi HeXOR

ich habs jetzt mal wirklich mit Threads gestaltet.
Das ergab allerdings gleich die nächsten Probleme.
In der Zeit in der die Verbindung aufgebaut wird und die Anwendung jetzt nicht mehr blockiert ist, kann man die eigentlichen Befehle über den Telnet schon drücken. :cry:
Ich habe sie nun bis zum Abschluß des verbindens einfach ausgeblendet. <)

Nun muß der User halt bei dem obigen Fehler eine Minute auf ausgeblendete Menüs schauen. :lol:
So ein kleiner Ping wäre doch noch die bessere Lösung.
Keiner was im Peto?

Bye André

Re: Computer und Port bereit ?

Verfasst: 10.03.2011 01:19
von Bisonte
Ich hab vor längerer Zeit mal ein "OpenNetwork" mit einem Timeout gefunden, weiss aber leider nicht mehr wo,
und wer den schrieb... aber ich poste ihn hier mal :

Timeout wird hierbei in Sekunden angegeben !

Mit dieser Prozedur, teste ich immer aus, ob der Server überhaupt da ist.
Eigentlich reicht eine Sekunde als Timeout, wenn der Port erreichbar ist, springt er eh gleich weiter ...

Code: Alles auswählen

Procedure.i OpenNetworkEx(ServerName.s,Port.l,TimeOut.l = 1,Type.l = #PB_Network_TCP) ; TimeOut in Sekunden

;##### Von Sicro : 
;##### Forenbeitrag : http://purebasic.fr/german/viewtopic.php?t=5192&start=38
  
  Protected WSAD.WSADATA, TV.TIMEVAL, Addr.SOCKADDR_IN, *HostInfo.HOSTENT, Write_FD.FD_SET
  Protected S.l, Switch.l, Retval.l, ServerIP.s
  
  TV\tv_sec = TimeOut
  Switch = #True
 
  If Type = #PB_Network_UDP
    ProcedureReturn OpenNetworkConnection(ServerName,Port,#PB_Network_UDP)
  EndIf
 
  If WSAStartup_($202,@WSAD)
    ProcedureReturn #False
  EndIf
 
  *HostInfo = gethostbyname_(@ServerName)
  If *HostInfo
    ServerIP = StrU(PeekB(PeekL(*HostInfo\h_addr_list)),0) + "."
    ServerIP + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 1),0) + "."
    ServerIP + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 2),0) + "."
    ServerIP + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 3),0)
  EndIf

  S = SOCKET_(#AF_INET,#SOCK_STREAM,#IPPROTO_TCP)
  If S = #SOCKET_ERROR
    WSACleanup_()
    ProcedureReturn #False
  EndIf
 
  ioctlsocket_(S,#FIONBIO,@Switch)
 
  With Addr
    \sin_addr = inet_addr_(ServerIP)
    \sin_port = htons_(Port)
    \sin_family = #AF_INET
  EndWith
  connect_(S,@Addr,SizeOf(Addr))
 
  With Write_FD
    \fd_count = 1
    \fd_array[0] = S
  EndWith
  Repeat
    Retval = select_(0,0,@Write_FD,0,@TV)
  Until Retval >= 0
 
  closesocket_(S)
  WSACleanup_()
  
  If Retval
    ProcedureReturn OpenNetworkConnection(ServerName,Port)
  EndIf
EndProcedure

InitNetwork()

Result = OpenNetworkEx("www.meinserver.de",8085, 1)

If Result
  Debug "Server Online"
Else
  Debug "Server Offline"
EndIf


Re: Computer und Port bereit ?

Verfasst: 11.03.2011 09:14
von Shardik
Bisonte hat geschrieben:Ich hab vor längerer Zeit mal ein "OpenNetwork" mit einem Timeout gefunden, weiss aber leider nicht mehr wo,
und wer den schrieb...
Sicro: http://www.purebasic.fr/german/viewtopi ... 2&start=38

Re: Computer und Port bereit ?

Verfasst: 11.03.2011 13:10
von Elektrolurch
Hi

Ich habe mittlerweile selbst einen kleinen Ping gebastelt.

Code: Alles auswählen

#PING_TIMEOUT = 1000
Global IP.s   = "192.168.72.1"

Procedure Ping ()
  lngHPort     = IcmpCreateFile_()
  strMessage.s = "Echo This Message back to me"
  MsgLen       = Len(strMessage)
  *buffer      = AllocateMemory(SizeOf(ICMP_ECHO_REPLY) + MsgLen)
  lngDAddress  = MakeIPAddress(Val(StringField(IP.s, 1, ".")), Val(StringField(IP.s, 2, ".")), Val(StringField(IP.s, 3, ".")), Val(StringField(IP.s, 4, ".")))
  ECHO.ICMP_ECHO_REPLY
  If IcmpSendEcho_(lngHPort, lngDAddress, @strMessage, MsgLen, #Null, *buffer, SizeOf(ICMP_ECHO_REPLY) + MsgLen, #PING_TIMEOUT)
    CopyMemory(*Buffer, ECHO, SizeOf(ICMP_ECHO_REPLY))
    PTime.f = ECHO\RoundTripTime
    ProcedureReturn PTime.f
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
If Ping ()
   Debug "Starte Telnet"
Else
  Debug "Keine Chance IP gibt es nicht"
EndIf
Damit sehe ich innerhalb einer Sekunde ob die IP (das Gerät) vorhanden ist.
Der gesperrte Port kommt sowieso schnell mit der Ablehnung zurück.
Also alles wieder gut.

BYe André

Re: Computer und Port bereit ?

Verfasst: 11.03.2011 18:31
von Bisonte
Shardik hat geschrieben:
Bisonte hat geschrieben:Ich hab vor längerer Zeit mal ein "OpenNetwork" mit einem Timeout gefunden, weiss aber leider nicht mehr wo,
und wer den schrieb...
Sicro: http://www.purebasic.fr/german/viewtopi ... 2&start=38
Danke ;)

Werd ich gleich mal als kommentar einbauen ...

P.S.:
@Elektrolurch :Wenn ich deinen Ping nutze, sagt der mir IMMER offline ...(Ja : Die IP existiert)
Und ich kann auch nirgends den Port entdecken den du dort nutzen willst....
Hilf mir mal auf die Sprünge bitte ;)

Re: Computer und Port bereit ?

Verfasst: 11.03.2011 20:14
von Elektrolurch
Hi Bisonte

ich habe den Ping heute Miitag in der Pause gebastelt.
Er lief unter XP.
Nun habe ich Zuhause den Code von hier unter Win 7 laufen lassen und er läuft auch.
Ich kann also momentan deine Probleme nicht nachvollziehen.
Ich muß gestehen das meiste ist "gegutenbergt".

Ich habe es auch nur dem
Verbindung = OpenNetworkConnection(IP_Adresse.s, 23)
voran gestellt. Damit habe ich das ausgeschaltete Gerät und das ewige warten bis zum Fehler auf eine Sekunde reduziert.
Kommt der Ping nicht durch breche ich die Aktion mit der Fehlermeldung "Gerät nicht Online" ab.
Klappt der Ping ist das Gerät Online und ich kann versuchen den den Port zu öffnen. Ist der Telnet deaktiviert, wird ja die Anfrage sofort abgelehnt. Somit kann ich sagen Gerät läuft aber Telnet deaktiviert. Erhalte ich Zugang ist alles in Ordnung und ich "bin drin" :allright:

Ich hoffe ich konnte mich verständlich ausdrücken.

Warum es bei dir aber nicht läuft, bringt mich ins grübeln.
Die IP kannst du mit einem anderen Programm anpingen?
Den evtl. Umbruch in der langen Zeile, der IP Erzeugung?
Pingzeit zu lange? evtl Timeout verlängern?

Gibt es hier jemanden bei dem es auch geht, oder auch nicht geht?

BYe André

Re: Computer und Port bereit ?

Verfasst: 11.03.2011 20:42
von ts-soft
Elektrolurch hat geschrieben: Gibt es hier jemanden bei dem es auch geht, oder auch nicht geht?

BYe André
"192.168.220.100" geht nicht (mein PC)
"192.168.220.1" geht (Router)

Re: Computer und Port bereit ?

Verfasst: 11.03.2011 21:04
von Elektrolurch
Hi
Danke ts-soft du hast mich auf den richtigen Weg gebracht.
Ich habe es einmal modifiziert.

Code: Alles auswählen

#PING_TIMEOUT = 1000
Global IP.s   = "192.168.1.3"

Procedure Ping ()
  lngHPort     = IcmpCreateFile_()
  strMessage.s = "Echo This Message back to me"
  MsgLen       = Len(strMessage)
  *buffer      = AllocateMemory(SizeOf(ICMP_ECHO_REPLY) + MsgLen)
  lngDAddress  = MakeIPAddress(Val(StringField(IP.s, 1, ".")), Val(StringField(IP.s, 2, ".")), Val(StringField(IP.s, 3, ".")), Val(StringField(IP.s, 4, ".")))
  ECHO.ICMP_ECHO_REPLY
  If IcmpSendEcho_(lngHPort, lngDAddress, @strMessage, MsgLen, #Null, *buffer, SizeOf(ICMP_ECHO_REPLY) + MsgLen, #PING_TIMEOUT)
    CopyMemory(*Buffer, ECHO, SizeOf(ICMP_ECHO_REPLY))
    PTime.f =  ECHO\RoundTripTime
    If PTime.f < 1 : PTime.f = 1 :EndIf
    ProcedureReturn PTime.f
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
If Ping ()
   Debug "Starte Telnet"
Else
  Debug "Keine Chance IP gibt es nicht"
EndIf
Das Problem ist folgendes, wenn man sich selbst anpingt oder ganz schnell ist, dann ist die Pingzeit kleiner 1ms.
Das hat zur Folge, dass die Prozedur 2 mal 0 als Ergebnis liefert.
Ich habe nun bei erfolgreichem Ping einfach den Minimalwert auf 1ms angehoben.
Nun sollte es Kugelsicher sein.
Viel Spaß damit.

BYe André