Seite 4 von 5
Verfasst: 17.07.2007 01:40
von Sicro
Ich habe hier auch noch eine Lösung gebastelt:
Code: Alles auswählen
InitNetwork()
Procedure OpenNetworkConnectionEx(ServerName.s,Port.l,TimeOut.l,Type.l = #PB_Network_TCP)
Protected ID.l, Output.s
#Flags = #PB_Program_Hide | #PB_Program_Open | #PB_Program_Read
If Type = #PB_Network_TCP
ID = RunProgram("ping","-w " + Str(TimeOut) + " -n 1 " + ServerName,"",#Flags)
WaitProgram(ID)
While AvailableProgramOutput(ID)
Output + ReadProgramString(ID)
Wend
CloseProgram(ID)
Else
ProcedureReturn OpenNetworkConnection(ServerName,Port,#PB_Network_UDP)
EndIf
If Not FindString(Output,"berschreitung der Anforderung",1)
ProcedureReturn OpenNetworkConnection(ServerName,Port,Type)
Else
ProcedureReturn -1
EndIf
EndProcedure
Define ID.l = OpenNetworkConnectionEx("www.purebasic.com",80,5000)
If ID > 0
Debug "Verbindung hergestellt"
CloseNetworkConnection(ID)
Else
Debug "TimeOut eingetreten"
EndIf
Mfg DerProgger
Verfasst: 17.07.2007 09:14
von legion
Gute Lösung !
Funktioniert tadellos !
Lg. Legion
Verfasst: 17.07.2007 15:54
von DarkDragon
legion hat geschrieben:Gute Lösung !
Funktioniert tadellos !
Lg. Legion
Funktioniert nur seine? Ich finde seine nicht so toll wie meine. Immerhin benötigt seine Lösung das Programm "ping".
Außerdem hat er noch Type drin, obwohl es nur bei TCP sinn macht. Bei UDP wäre OpenNetworkConnection sowieso nach wenigen millisekunden durch.
Verfasst: 17.07.2007 18:00
von Sicro
Keine Sorge, bei mir hat dein Code ebenfalls prima geklappt. Nur gefällt mir das brutale Beenden des Threads (im Grunde wie KillThread()) nicht.
Zu deiner Kritik:
Stimmt, bei UDP ist es völlig sinnlos. Ich habe es ergänzt, danke

Das Ping-Programm habe ich verwendet, weil der Aufwand mit diesem geringer ist. Als nachteilig kann ich das nicht sehen, das hat doch bestimmt jeder auf seiner Windowskiste. Wem das trotzdem nicht gefällt, kann es ja direkt über die WinAPI machen.
Mfg DerProgger
Verfasst: 17.07.2007 18:09
von DarkDragon
DerProgger hat geschrieben:Das Ping-Programm habe ich verwendet, weil der Aufwand mit diesem geringer ist. Als nachteilig kann ich das nicht sehen, das hat doch bestimmt jeder auf seiner Windowskiste.
Ping empfängt aber doch auch nur ein Pong von der Serverseite von einem bestimmten Port (~53 wars doch). Auf jeden fall: Wenn der, der deine funktion benutzt auf den Server mit nem Port verbindet, den der Server gar nicht "offen" hat wirds kritisch, weil dann Pingt der ihn auf einem "offenen" Port und versucht auf einen "geschlossenen" Port zuzugreifen(Folglich: 20 sekunden timeout standard)
Verfasst: 17.07.2007 23:01
von legion
DarkDragon hat geschrieben:
Funktioniert nur seine? Ich finde seine nicht so toll wie meine. Immerhin benötigt seine Lösung das Programm "ping".
Finde deine Lösung auch super !
Alle Wege führen nach Rom, einer über Wien, ein anderer über Tokio.
Habe nicht den ganzen Tread gelesen, entschuldige.
Lg. Legion
Verfasst: 18.07.2007 12:55
von Sicro
DarkDragon hat geschrieben:Wenn der, der deine funktion benutzt auf den Server mit nem Port verbindet, den der Server gar nicht "offen" hat wirds kritisch, weil dann Pingt der ihn auf einem "offenen" Port und versucht auf einen "geschlossenen" Port zuzugreifen(Folglich: 20 sekunden timeout standard)
Daran habe ich auch gedacht und dazu einen Test gemacht. Ergebnis: OpenNetworkConnection macht - jedenfalls bei mir - beim Verbinden zu einem geschlossenen Port nur eine Pause von einer Sekunde.
Mir ist bei meinem Code allerdings aufgefallen, dass manchmal ein Timeout gemeldet wird, obwohl eine Verbindung aufgebaut werden könnte. Bemerkbar wird dies vor allem beim mehrfachem Aufrufen. Ich werde später mal testen, ob das bei einem Ping direkt über die WinAPI ebenfalls noch so ist.
Des Weiteren habe schon versucht, den Verbindungstest über die WinAPI-Funktion "connect_()" durchzuführen, aber dort tritt ein Timeout ebenfalls erst nach ca. 20 Sekunden ein. Vielleicht wäre hier ein Non-Blocking-Socket die Lösung, aber wie man solch ein Socket erstellt, habe ich noch nicht herausgefunden.
Mfg DerProgger
Verfasst: 18.07.2007 15:27
von DarkDragon
DerProgger hat geschrieben:Vielleicht wäre hier ein Non-Blocking-Socket die Lösung, aber wie man solch ein Socket erstellt, habe ich noch nicht herausgefunden.
Mfg DerProgger
Genau das hat der Code von MLK bewirkt: Er erstellt einen Non blocking Socket und wartet auf einen Verbindungsaufbau. Eine WSA... Funktion gibts extra dafür. Unter Linux weiß ich es nicht.
Verfasst: 18.07.2007 18:42
von Sicro
So, ich habe nun einen weiteren Code geschrieben. Dieser versucht eine Verbindung zum Server direkt über die WinAPI herzustellen und beendet anschließend die Verbindung gleich wieder. Konnte die Verbindung erfolgreich hergestellt werden, wird die Verbindung erneut mit der PB-Funktion hergestellt.
Code: Alles auswählen
EnableExplicit
InitNetwork()
Procedure OpenNetworkConnectionEx(ServerName.s,Port.l,TimeOut.l,Type.l = #PB_Network_TCP)
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
#TimeOut = 1 ; in Sekunden
Define ID.l = OpenNetworkConnectionEx("www.purebasic.com",80,#TimeOut)
If ID
Debug "Verbindung war erfolgreich"
CloseNetworkConnection(ID)
Else
Debug "Timeout oder Fehler"
EndIf
Mfg DerProgger
Verfasst: 18.07.2007 22:56
von legion
Super ! Wird immer besser !
Funktioniert auch unter Vista !
Lg. Legion