Hallo Leute,
weiß jemand wie man unter VOR dem einlesen der Daten von Winsock (RECV) feststellen kann wie viele Zeichen zum einlesen bereit stehen.
Es würde schon helfen wenn man irgendwie feststellen könnte ob überhaupt ein Zeichen empfangen wurde.
Es geht hier um ein altes Terminalprogramm welches unter PBCC läuft und jetzt um TCP/IP erweitert werden soll.
Bei den seriellen Schnittstellen ist es einfach möglich festzustellen wie viele Zeichen im Empfangspuffer bereit stehen. Für TCP/IP habe ich eine entsprechende Funktion nicht gefunden.
Gruß
Daffy
[PowerB] Anzahl der Zeichen die über TCP/IP empfangen wurden
[PowerB] Anzahl der Zeichen die über TCP/IP empfangen wurden
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
Hi,
dafür gibt es einen einfach Weg.
Dies ist ein Ausschnitt aus meinem Code zur Erkennung eines TCP Disconnects beim Client. Die benötigten Konstanten (für Linux / MacOS) findest du im Beitrag [crossplatform] Disconnect Event for Client
Dark
dafür gibt es einen einfach Weg.
Code: Alles auswählen
; Check if data is available?
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
RetVal = ioctlsocket_(hSocket, #FIONREAD, @Length)
CompilerElse
RetVal = ioctl_(hSocket, #FIONREAD, @Length)
CompilerEndIf
Dark
Mein Blog: http://fds-team.de/cms/
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
@Dark
Erst mal vielen Dank für den Hinweis.
Ist wenigstens schon mal ein Anhalt wo man schauen muss!
Allerdings habe ich das bis jetzt nicht zum Laufen gebracht.
So mal am Rande bemerkt: Ich kann es einfach nicht begreifen, wie man als Entwickler einer Programmiersprache (Hier geht es um den "Powerbasic Console Compiler" NICHT um Purebasic) einen Befehlssatz für den Zugriff auf TCP/IP "bauen" kann der es nicht ermöglicht die Anzahl der empfangenen Bytes festzustellen. Für den Zugriff auf die normalen seriellen Schnittstellen existiert dieser Befehl doch auch.
Die äquivalente Form in C wäre meines Wissens nach "Anzahl = RECV...)"
So aber nun mal Butter bei die Fische:
Eine Suche mit Google (Powerbasic %FIONREAD) ergab 8 !!! absolut unbrauchbare Ergebnisse!
z. B. so etwas hier
Kein Datentyp angegeben und nach dem was ich bis jetzt gefunden habe ist "BytesAvail" doch eigentlich ein Zeiger und keine Variable.
Der Autor behauptet allen Ernstes das das funktionieren würde. Das lässt noch nicht mal kompileren!
Laut Microsoft sieht die Funktion so aus:
Wenn ich das richtig verstanden habe dann ist der Rückgabewert ein "Integer" (Was für ein Integer 16bit? 32bit? ????bit?)
Was da zurückgegeben wird wissen die Götter.
Was ist SOCKET s ? Ein String (wohl kaum) soll wohl dieser geheimnisvolle "HANDLE" sein bei dem ich bei Powerbasic auch nirgens SICHER eine Auskunft darüber bekomme wie man von der mit "FREEFILE" vergebenen Nummer auf den "HANDLE" kommt. Ob das in dem oberen Beispiel stimmt? Keine Ahnung!
long cmd da vermute ich mal, das hier die Konstante die das Kommando "%FIONREAD" repräsentiert hin kommt. Auch hier weiß man nicht was mit "long" gemeint ist (unsigned / signed / trallala ...)
u_long *argp da vermute ich mal (bestätigt durch dein Beispiel) das hier ein Adresszeiger auf eine Variable vom Typ "mer waases net, mer forscht noch" hinkommt in der dann (so Gott will) die Anzahl der Zeichen die empfangen wurden stehen soll.
Hab nun stundenlang alles mögliche ausprobiert - Es kommt immer nur NULL.
Hab langsam die Nase voll von diesem SCHWACHSINN!
Gruß
Daffy
PS. Warum ich diese Frage nicht im PowerBasic Forum stelle?! Nun, da habe ich 3 Tage nach der Anmeldung noch immer keine Freischaltung der Anmeldung bekommen!
Erst mal vielen Dank für den Hinweis.
Ist wenigstens schon mal ein Anhalt wo man schauen muss!
Allerdings habe ich das bis jetzt nicht zum Laufen gebracht.
So mal am Rande bemerkt: Ich kann es einfach nicht begreifen, wie man als Entwickler einer Programmiersprache (Hier geht es um den "Powerbasic Console Compiler" NICHT um Purebasic) einen Befehlssatz für den Zugriff auf TCP/IP "bauen" kann der es nicht ermöglicht die Anzahl der empfangenen Bytes festzustellen. Für den Zugriff auf die normalen seriellen Schnittstellen existiert dieser Befehl doch auch.
Die äquivalente Form in C wäre meines Wissens nach "Anzahl = RECV...)"
So aber nun mal Butter bei die Fische:
Eine Suche mit Google (Powerbasic %FIONREAD) ergab 8 !!! absolut unbrauchbare Ergebnisse!
z. B. so etwas hier
Code: Alles auswählen
' Get the socket handle for windows
hSocket = FILEATTR(hSock, 2)
' Ask how many bytes are available
Result = ioctlsocket(hSocket, %FIONREAD, BytesAvail)
Kein Datentyp angegeben und nach dem was ich bis jetzt gefunden habe ist "BytesAvail" doch eigentlich ein Zeiger und keine Variable.
Der Autor behauptet allen Ernstes das das funktionieren würde. Das lässt noch nicht mal kompileren!
Laut Microsoft sieht die Funktion so aus:
Code: Alles auswählen
int ioctlsocket(
__in SOCKET s,
__in long cmd,
__inout u_long *argp
);
Was da zurückgegeben wird wissen die Götter.
Was ist SOCKET s ? Ein String (wohl kaum) soll wohl dieser geheimnisvolle "HANDLE" sein bei dem ich bei Powerbasic auch nirgens SICHER eine Auskunft darüber bekomme wie man von der mit "FREEFILE" vergebenen Nummer auf den "HANDLE" kommt. Ob das in dem oberen Beispiel stimmt? Keine Ahnung!
long cmd da vermute ich mal, das hier die Konstante die das Kommando "%FIONREAD" repräsentiert hin kommt. Auch hier weiß man nicht was mit "long" gemeint ist (unsigned / signed / trallala ...)
u_long *argp da vermute ich mal (bestätigt durch dein Beispiel) das hier ein Adresszeiger auf eine Variable vom Typ "mer waases net, mer forscht noch" hinkommt in der dann (so Gott will) die Anzahl der Zeichen die empfangen wurden stehen soll.
Hab nun stundenlang alles mögliche ausprobiert - Es kommt immer nur NULL.
Hab langsam die Nase voll von diesem SCHWACHSINN!
Gruß
Daffy
PS. Warum ich diese Frage nicht im PowerBasic Forum stelle?! Nun, da habe ich 3 Tage nach der Anmeldung noch immer keine Freischaltung der Anmeldung bekommen!
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
Hi,
eine Suche bei Google nach "msdn data types" oder "windows data types" hätte dir als Ergebnis diese Seite gebracht: http://msdn.microsoft.com/en-us/library ... s.85).aspx auf der z.B. LONG und weitere Daten typen erklärt sind.
Noch besser ist es natürlich nach "C data types" zu suchen, da es sich hierbei um die Standard Datentypen von C handelt. Dann hättest du dies gefunden: http://www.cppreference.com/wiki/language/types. Hier werden alle Datentypen von C mit 32/64 bit und Betriebsystem erklärt.
Jetzt muss man nur noch wissen das u_long eine Abkürzung für unsigned long ist.
SOCKET erklärt dir die MSDN hier: http://msdn.microsoft.com/en-us/library ... s.85).aspx.
Wie du nun in PowerBasic an das Handle heran kommst kann ich dir auch nicht sagen.
Je nach dem wie groß das Programm ist, solltest es lieber in eine andere Sprache übersetzen in der du mehr Informationen findest als für PowerBasic. Könnte unter Umständen vll. schneller sein als die ganze Zeit nur rum zu probieren.
Die meisten Programme arbeiten auch ohne diese Möglichkeit. Es ist ja auch nicht wirklich notwendig. Wenn man TCP benutzt ist das ganze sowieso Stream basiert und die Daten können von dem Betriebsystem in beliebig viele Pakete unterteilt werden. Die Empfangsroutine muss also damit klar kommen das die Daten beliebig zerstückelt ankommen. Man übergibt einen Buffer mit einer bestimmten Größe an Recv, ist der nach dem Aufruf aufgebraucht, ruft man die Funktion nochmal auf. Die Funktion die sich um die Verarbeitung der Daten kümmert, muss ja sowieso damit klar kommen das diese total zerstückelt sind. Bei UDP ist es noch weniger ein Problem, da hier die Pakete durch die MTU eine feste maximal Größe haben. Daher weiß man schon wie groß der Buffer maximal sein muss.
Man sollte auch hier http://msdn.microsoft.com/en-us/library ... s.85).aspx die hinweiße zu FIONREAD beachten. (PS: da steht auch das argp ein Pointer auf ein unsigned long ist).
Je nach dem ob dies für TCP oder UDP verwendet wird unterscheidet sich der Rückgabewert. Bei UDP wird nämlich nur die Anzahl der Bytes für ein Packet zurück gegeben. Es wäre sonst ja auch nicht mehr möglich zu erkennen von wem die Daten sind, da ein UDP Socket daten von verschiedenen Empfängern erhalten kann.
Dark
eine Suche bei Google nach "msdn data types" oder "windows data types" hätte dir als Ergebnis diese Seite gebracht: http://msdn.microsoft.com/en-us/library ... s.85).aspx auf der z.B. LONG und weitere Daten typen erklärt sind.
Noch besser ist es natürlich nach "C data types" zu suchen, da es sich hierbei um die Standard Datentypen von C handelt. Dann hättest du dies gefunden: http://www.cppreference.com/wiki/language/types. Hier werden alle Datentypen von C mit 32/64 bit und Betriebsystem erklärt.
Jetzt muss man nur noch wissen das u_long eine Abkürzung für unsigned long ist.
SOCKET erklärt dir die MSDN hier: http://msdn.microsoft.com/en-us/library ... s.85).aspx.
Wie du nun in PowerBasic an das Handle heran kommst kann ich dir auch nicht sagen.
Je nach dem wie groß das Programm ist, solltest es lieber in eine andere Sprache übersetzen in der du mehr Informationen findest als für PowerBasic. Könnte unter Umständen vll. schneller sein als die ganze Zeit nur rum zu probieren.
Die Frage kannst du auch gleich an Fred weiter geben, denn PureBasic kennt dafür auch keinen Befehl.Daffy0815 hat geschrieben:Ich kann es einfach nicht begreifen, wie man als Entwickler einer Programmiersprache (Hier geht es um den "Powerbasic Console Compiler" NICHT um Purebasic) einen Befehlssatz für den Zugriff auf TCP/IP "bauen" kann der es nicht ermöglicht die Anzahl der empfangenen Bytes festzustellen. Für den Zugriff auf die normalen seriellen Schnittstellen existiert dieser Befehl doch auch.
Die meisten Programme arbeiten auch ohne diese Möglichkeit. Es ist ja auch nicht wirklich notwendig. Wenn man TCP benutzt ist das ganze sowieso Stream basiert und die Daten können von dem Betriebsystem in beliebig viele Pakete unterteilt werden. Die Empfangsroutine muss also damit klar kommen das die Daten beliebig zerstückelt ankommen. Man übergibt einen Buffer mit einer bestimmten Größe an Recv, ist der nach dem Aufruf aufgebraucht, ruft man die Funktion nochmal auf. Die Funktion die sich um die Verarbeitung der Daten kümmert, muss ja sowieso damit klar kommen das diese total zerstückelt sind. Bei UDP ist es noch weniger ein Problem, da hier die Pakete durch die MTU eine feste maximal Größe haben. Daher weiß man schon wie groß der Buffer maximal sein muss.
Man sollte auch hier http://msdn.microsoft.com/en-us/library ... s.85).aspx die hinweiße zu FIONREAD beachten. (PS: da steht auch das argp ein Pointer auf ein unsigned long ist).
Je nach dem ob dies für TCP oder UDP verwendet wird unterscheidet sich der Rückgabewert. Bei UDP wird nämlich nur die Anzahl der Bytes für ein Packet zurück gegeben. Es wäre sonst ja auch nicht mehr möglich zu erkennen von wem die Daten sind, da ein UDP Socket daten von verschiedenen Empfängern erhalten kann.
Dark
Mein Blog: http://fds-team.de/cms/
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
@Dark
Erst mal zur Erklärung:
Ich habe über viele Jahre dieses Programm welches ein Terminalprogramm mit integrierten Preprozessor für ein Microcontrollerbasierendes Prozessbasic (Marke Eigenbau) ist entwickelt.
Ich habe das Programm damals (in einem Anflug geistiger Umnachtung) mit dem Powerbasic Console Compiler geschrieben und eine Umstellung auf etwas Anderes ist heute nicht mehr so ohne weiteres möglich.
Bei einem anderen Projekt habe ich sehr schnell die Konsequenzen aus der miesen Dokumentation und dem absolut unterirdischen Support gezogen und bin zu Purebasic gewechselt.
Was die Bemerkung zu "Fred" betrifft so muss ich zu dessen "Ehrenrettung" anmerken, das PureBasic auch nirgens den Anspruch erhebt irgendwelche Kommandos / Funktionen zur TCP/IP Kommunikation in sich zu integrieren - Das tut PowerBasic aber sehr wohl!!!
Die machen zwar wohl auch nicht anderes als das Ganze an die Windows-API weiterzureichen aber offenbar sind sie selbst dazu unfähig.
Da finde ich die PureBasic-Programmierer ehrlicher denn die sagen gleich "machs über die WinAPI".
Es ist mir durchaus klar, das TCP/IP als Träger für eine zeichenorientierte Datenübertragung nicht gerade gut geeignet ist aber es ist schon eine feine Sache wenn man via Internet direkt auf Geräte zugreifen kann selbst dann wenn diese in Mexico stehen.
Da die Sache in keiner Kombination zum Laufen zu bringen ist (ich habe wirklich ALLE ausprobiert) habe ich jetzt halt den Weg über die "TimeOut-Option" bei der Open-Anweisung gewählt und diesen auf 1 Millisekunde gesetzt.
So ganz nebenbei ist mir da bei Powerbasic noch ein weiterer Murks aufgefallen: Die machen groß Werbung damit dass sie mit Megabytegroßen Strings umgehen können. Was sie nicht sagen, dass wenn ein String größer als 32767 Zeichen wird sämtliche Stringoperationen (z. B. Mid$, Left$ ...) um den Faktor 50 langsamer werden.
Hier meine Lösung für PBCC (nur die relevanten Teile)
Gruß Daffy
PS. Wer mal Tipps zur Assembler-Programmierung von 51-kompatiblen Microcontrollern (insbesondere MAXIM-DALLAS / SILABS) braucht kann sich gerne an mich wenden.
Erst mal zur Erklärung:
Ich habe über viele Jahre dieses Programm welches ein Terminalprogramm mit integrierten Preprozessor für ein Microcontrollerbasierendes Prozessbasic (Marke Eigenbau) ist entwickelt.
Ich habe das Programm damals (in einem Anflug geistiger Umnachtung) mit dem Powerbasic Console Compiler geschrieben und eine Umstellung auf etwas Anderes ist heute nicht mehr so ohne weiteres möglich.
Bei einem anderen Projekt habe ich sehr schnell die Konsequenzen aus der miesen Dokumentation und dem absolut unterirdischen Support gezogen und bin zu Purebasic gewechselt.
Was die Bemerkung zu "Fred" betrifft so muss ich zu dessen "Ehrenrettung" anmerken, das PureBasic auch nirgens den Anspruch erhebt irgendwelche Kommandos / Funktionen zur TCP/IP Kommunikation in sich zu integrieren - Das tut PowerBasic aber sehr wohl!!!
Die machen zwar wohl auch nicht anderes als das Ganze an die Windows-API weiterzureichen aber offenbar sind sie selbst dazu unfähig.
Da finde ich die PureBasic-Programmierer ehrlicher denn die sagen gleich "machs über die WinAPI".
Es ist mir durchaus klar, das TCP/IP als Träger für eine zeichenorientierte Datenübertragung nicht gerade gut geeignet ist aber es ist schon eine feine Sache wenn man via Internet direkt auf Geräte zugreifen kann selbst dann wenn diese in Mexico stehen.
Da die Sache in keiner Kombination zum Laufen zu bringen ist (ich habe wirklich ALLE ausprobiert) habe ich jetzt halt den Weg über die "TimeOut-Option" bei der Open-Anweisung gewählt und diesen auf 1 Millisekunde gesetzt.
So ganz nebenbei ist mir da bei Powerbasic noch ein weiterer Murks aufgefallen: Die machen groß Werbung damit dass sie mit Megabytegroßen Strings umgehen können. Was sie nicht sagen, dass wenn ein String größer als 32767 Zeichen wird sämtliche Stringoperationen (z. B. Mid$, Left$ ...) um den Faktor 50 langsamer werden.
Hier meine Lösung für PBCC (nur die relevanten Teile)
Code: Alles auswählen
Global ServerName$
Global PortNum$
GLOBAL SocketNum&
GLOBAL Buffer$
GLOBAL Packet$
FUNCTION PBMAIN () AS LONG
'
'......
'
TCP OPEN PORT VAL(PortNum$) AT ServerName$ AS SocketNum& TIMEOUT 1
'
'.....
'
SUB Senden(Sende$)
TCP SEND SocketNum&, Sende$
END SUB
'
FUNCTION EMPFANGENEZEICHEN&
TCP RECV SocketNum&, 1, Buffer$
If Buffer$ <> "" Then
Packet$ = Packet$ + Buffer$
End IF
EMPFANGENEZEICHEN& = LEN(Packet$)
END FUNCTION
'
FUNCTION EMPFANGEN$(Anzahl&)
Laenge& = LEN(Packet$)
Do While Laenge& < Anzahl&
TCP RECV SocketNum&, Anzahl& - Laenge&, Buffer$
If Buffer$ <> "" Then
Packet$ = Packet$ + Buffer$
Laenge& = LEN(Packet$)
End If
Loop
X$ = Left$(Packet$, Anzahl&)
Packet$ = Mid$(Packet$, Anzahl& + 1)
EMPFANGEN$ = X$
END FUNCTION
Gruß Daffy
PS. Wer mal Tipps zur Assembler-Programmierung von 51-kompatiblen Microcontrollern (insbesondere MAXIM-DALLAS / SILABS) braucht kann sich gerne an mich wenden.
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
-
- Beiträge: 6291
- Registriert: 29.08.2004 08:37
- Computerausstattung: Hoffentlich bald keine mehr
- Kontaktdaten:
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
[Offtopic]Das gehört wohl eher in Andere Sprachen, wenn es hier um PowerBasic geht. Die restlichen Foren sind allesamt für PureBasic da.[/OffTopic]
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Re: Anzahl der Zeichen die über TCP/IP empfangen wurden
@DarkDragon
Stimmt, Du hast recht!
Hatte übersehen das es eine solche Rubrik gibt.
Gruß
Daffy
Stimmt, Du hast recht!
Hatte übersehen das es eine solche Rubrik gibt.
Gruß
Daffy
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert