 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 14.12.2012, 09:45 Titel: Bilder versenden mit TSNE |
|
|
Ich habe, wie ihr sicherlich bemerkt habt, nicht wirklich Ahnung von Sockets
Deshalb habe ich ein paar Fragen.
Ich möchte vom Socketserver (TSNE) einem Client ein Bild senden.
Kann mir jemand bitte einen Beispielcode für das Senden und Empfangen geben?
Vielen Dank. |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 14.12.2012, 15:33 Titel: |
|
|
Was hat das so direkt mit Sockets zu tun?
Du wirst doch vermutlich irgendeine Form von Protokoll haben — du musst dein Bild irgendwie serialisieren (als Anfang würde es sich anbieten, einen Header der Art Höhe, Breite, BPP etc. und danach einfach die Pixeldaten zu schicken – oder einfach ein vorhandes Bildformat wie PNG oder TGA zu benutzen) und am anderen Ende wieder rekonstruieren.
Das hat nichts mit Sockets zu tun, sondern ist ein etwas generelleres Problem, was erstmal unabhängig davon ist, ob ich als Transportschicht Sockets benutze oder HTTP oder ICMP oder DNS-TXT — oder welche spezifische API du da genau verwendest...
Siehe auch
http://de.wikipedia.org/wiki/Serialisierung
http://de.wikipedia.org/wiki/Marshalling
http://de.wikipedia.org/wiki/OSI-Modell |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 16.12.2012, 01:29 Titel: |
|
|
@stevie1401 ... wie 23898 schon geschrieben hat, brauchst du auf jeden fall ein protokoll, damit die übertragung "sicher" ist.
dann kannst du einfach das bild in einen fb.image laden, so wie du es auch anzeigen würdest.
anschliessend liest du das bild pixel für pixel aus, speicherst den wert in einen string, und verschickst das sammt protokoll via tsne_data_send.
auf der anderen seite empfängst du den datenstrom. die daten schickst du dann durch deine protokoll auswert funktion, ud erhällst dadurch wieder einen string mit dem bild.
anschliessend die daten vom string in ein erzeugtes fb.image schreiben. und schon ists da.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 08.02.2013, 09:56 Titel: |
|
|
Ich habe mir inzwischen eine Routine gebaut, mit der ich per String Bilder übertragen kann.
Das Problem ist allerdings, dass der TSNE_INT_BufferSize von 7936 viel zu klein ist.
Kann ich den beliebig erhöhen? Was passiert, wenn ich diesen erhöhe? |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 10:45 Titel: |
|
|
nein. an den Internen Werten solltest du keinesfalls herumschrauben.
Wieso zu klein? .. was hat die IP-Packet-Puffergröße mit der Größe deines Bildes zu tun?
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 08.02.2013, 11:46 Titel: |
|
|
Der String, den ich vom Client aus an den Server sende ist 8758 Zeichen gross.
Es kommen dort aber nur 822 Zeichen an. |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 12:15 Titel: |
|
|
das liegt aber nicht am der internen TSNE Variable.
Ich vermute, das du bei der Konvertierung oder der Übergabe der Binärdaten in den String etwas vermurkst.
zeig mal diese Funktion, die du da geschrieben hast.
Wichtig ist, das du 1. ByRef übergibst, keine ZString's nutzt, und auch verhinderst, das Freebasic die Daten zu irgend einem Zeitpunkt in einen ZString umwandelt.
ZStrings sidn 0 Terminirte Variablen. Sprich, wenn ein Chr(0) im String enthalten ist, sieht es für Freebasic so aus, als wäre dort die Zeichenkette zu ende. Bei einem FB.String (Regulärer String) passiert das nicht. Nur bei ZString / WString.
Das heist auch, das du kein RETURN für den String nutzen kannst. Returns sind ZString Variablen.
Code: |
Function Test1() as String
Return "Hallo" & Chr(0) & "Test"
End Function
Print Len(Test1())
|
im vergleich zu
Code: |
Sub Test2(ByRef R_Data as String)
R_Data = "Hallo" & Chr(0) & "Test"
End Sub
Dim TVar as String
Test2(TVar)
Print Len(TVar)
|
Das gilt im übrigem auch auf der Empfangsseite.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 08.02.2013, 12:28 Titel: |
|
|
ThePuppetMaster hat Folgendes geschrieben: | Das heist auch, das du kein RETURN für den String nutzen kannst. Returns sind ZString Variablen.
Code: |
Function Test1() as String
Return "Hallo" & Chr(0) & "Test"
End Function
Print Len(Test1())
|
im vergleich zu
Code: |
Sub Test2(ByRef R_Data as String)
R_Data = "Hallo" & Chr(0) & "Test"
End Sub
Dim TVar as String
Test2(TVar)
Print Len(TVar)
|
|
Hi TPM,
es scheint so, als hätte sich das inzwischen geändert:
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 08.02.2013, 12:29 Titel: |
|
|
Der String, den ich sende, sieht in etwa so aus:
<<bild>>002564985623548<</bild>>
Nur dass die Zahlen zwischen <<bild> und <</bild> natürlich viel länger sind.
Der Server guckt, ob in der ankommenden Nachticht ein <</bild>> ist.
Wenn er das findet, fischt er sich den String zwischen <<bild>> und <</bild>> heraus.
Ich habe dies mit verschiedenen Bildern getestet.
Der Server empfängt immer mehrere Strings verschiedener Länge.
Die maximale empfangbare Größe liegt dabei bei ca 7900 Zeichen.
Ich versende ganz normale Strings, keine ZStrings.
Andersrum geht es übrigens.
Der Client bekommt, wenn der Server ein Bild mit <<bild>235654...<</bild>> sendet, den vollen String. Der Client ist allerdings in GFA-Basic geschrieben. |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 12:44 Titel: |
|
|
@Sebastian ... oha ... das is ja cool. naja.. ich workel ja noch mit 0.20
@stevie1401 ... Naja... ich kann dir da nur wenig helfen, wenn ich keinen source sehe, der das macht. Ich kann nur vermutungen aufstellen. Aber, ich kann dir sicher sagen, das es nicht an TSNE selbst liegen kann. Schliesslich überträgt mein Galerieserver massenhaft Bilder, und das Problemlos.
Ich kan nur vermuten, das du entweder beim Transport eienn Fehler machst, oder bei der Konvertierung.
Als Tip könnte ich dir Vorschlagen, das du das Lokal testest.
Nutze diese Funktionen hier, um die Daten zu senden und zu Empfangen. Sie sind TSNE-Like, und verarbeiten die Daten so wie sie auch TSNE verarbeitet.
Code: |
'Empfänger
Sub TSNETEST_New_Data(ByVal V_TSNEID as UInteger, ByRef V_Data as String)
Print "Empfange: >" & V_Data & "<"
End Sub
'Sende Funktion
Function TSNETEST_Data_Send(ByRef V_TSNEID as UInteger, ByRef V_Data as String, ByRef R_BytesSend as UInteger = 0, ByVal V_IPA as String = "", ByVal V_Port as UShort = 0) as Integer
Dim T as String
Dim TBlockLen as UInteger = 7936
Dim TLen as UInteger = TBlockLen
For X as UInteger = 1 to Len(V_Data) Step TBlockLen
If Len(V_Data) - X < TBlockLen Then TLen = Len(V_Data) - X + 1
TSNETEST_New_Data(V_TSNEID, Mid(V_Data, X, TLen))
R_BytesSend += TLen
Next
Return 1
End Function
TSNETEST_Data_Send(1, "Das ist ein Test")
|
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 08.02.2013, 13:24 Titel: |
|
|
Das Problem ist folgende Zeile in unterer Sub:
.V_Data = ""
Damit wird ja alles geschöscht, was vorher addiert wurde.
Code: |
Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
If V_CallBackPtr = 0 Then TSNE_Disconnect(V_TSNEID): Exit Sub
Dim As Integer aID
Dim As String aMess
With *V_CallBackPtr
.V_Data += V_Data
Print "[CLIENT] DATA: " & V_TSNEID & " " & .V_IPA & " DataLen:"; Len(.V_Data)
'Nur zu dem clienten senden, vond em wir daten empfangen haben
' TSNE_Data_Send(V_TSNEID, "Habe daten von dir empfangen!")
' TSNE_Data_Send(V_TSNEID, MessageFromClient)
'print MessageFromClient
'zu allen clienten senden
'SendToAll("Hab von " & .V_IPA & " datenempfangen!")
'print messagefromclient
'check_Client_Nachricht(ClientId,MessageFromClient,ClientIpp)
aMess=.v_data
aID=V_TSNEID
ClientIpp= V_CallBackPtr->V_IPA
check_Client_Nachricht(aID,aMess,ClientIpp)
.V_Data = ""
End With
End Sub |
|
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 13:49 Titel: |
|
|
Ich kann es nur immer wieder sagen ... es ist extrem wichtig, das du ein sauberes Protokoll implementierst.
Es gibt so viele Variablen, die auf der Lokalen Maschien anders ablaufen als im Internet.
Ein Punkt ist z.B. das die Daten in viel kleineren Blöcken gesendet werden. Dies sind IP-Pakete, welche grob 8KByte groß sind. Egal wie lang deine Nachricht ist, sie werden in ca. 8K Blöcke von explizieter Datengröße gepackt.
Entsprechend musst du auf deiner Seite dafür sorgen, das:
1. die Datenblöcke wieder sauber aneinander gehengt werden
2. Ein Protokoll existiert, das die Daten verarbeitet und nichts davon löscht
3. Überschüssige Daten nicht verloren gehen.
Ich vermute, das du 2 und 3 nicht sauber umsetzt.
Du kopierst die daten in eine Globale variable (.V_Data). Sie speichert alles so wie es gesendet wurde. Anschliessend verarbeitest du die nachricht mit check_client_nachricht. Zum schluß löscht du die Variable wieder. Ansich ok, wenn auch wirklich nichts mehr übrig sein sollte.
aber, stell dir vor, du hast in .V_Data folgendes Stehen
Code: |
<bild>1234</bild><bild>12
|
dann würde die lesefunktion das erste erkennen, das zweite nicht emhr, weils nicht komplett is, und es einfach verwerfen.
danach trifft der letzte block ein
der wird jetzt an die leere var gehängt, udn wieder die verarbeitugn gestartet.
da das TAG fehlt, wirds ignoriert, und dann boom.
es sollte eher so sein, das die Verarbeitende Routine die Daten ausliest, verarbeitet, udn den überschus wieder in die .V_Data schreibt, so das nachfolgende Daten an den überschüssigen angehengt werden, und somit nicht verloren sind.
Aber, wie ich schon so oft gesagt habe, und ich kann mich hier nur immer und immer wieder, wiederholen: das A und O ist ein Sauberes Protokoll zur Übertragung der Daten.
Eines, das erkennt, wenn Fehler im Datenstrom aufgetreten sind (zumindest extrem rudimentär), udn entsprechend aktionen händelt.
EDIT
Bezüglich der Datenübertragung:
Du kannst nicht davon ausgehen, das pro TSNE_Data_Send aufruf auch NUR die Daten übetragen werden, udn als Block so wie du die funktion aufgerufen hast, auch ankommen.
Das Betriebssystem fasst unter umständen die 2 Aufrufe zu einem Zusammen und verschickt dieses als ganzes.
so kann z.B. aus:
Code: |
TSNE_Data_Send(0, "Test")
TSNE_Data_Send(0, "Hallo")
|
Vom Betriebssystem aus es so gepackt werden, das es vergleichbar zu einem
Code: |
TSNE_Data_Send(0, "TestHallo")
|
wird.
und wenn du hier keine massnahmen zur filterung bzw. ein Protokoll einführst, dann wirst du hier Probleme bekommen!
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
ichhalt
Anmeldungsdatum: 26.01.2013 Beiträge: 39
|
Verfasst am: 08.02.2013, 15:14 Titel: |
|
|
Wie wuerde denn so ein sauberes protokoll aussehn? |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 15:17 Titel: |
|
|
Prinzipiel sollte ein Protokoll sehr logisch vorgehen. Dabei sollten Mechanissmen integriert werden, die erkennen ob die daten komplett eingetroffen sind, und ob die daten fehlerfrei übertragen wurden (was aber vernachlässigt werden kann, das solceh masnahmen bereits in TCP enthalten sind).
wenn man noch dafür sorgt, das die daten auch sauber strukturiert werden, dann ist das senden und das auslesen der empfangenden daten ebenfalls sehr einfach und übersichtlich.
ein beispiel / ne art vorlage ist hier zu finden:
http://ops.ath.cx/code?id=260
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 08.02.2013, 15:53 Titel: |
|
|
Naja... http is auch nur "bedingt" gut.Die einzigste statische massnahme der datenlänge ist zum einen durch die trennung mit chr(13, 10, 13, 10) gegeben, udn durch die content-length ODER das connection: close (was jedoch ein unsicheres verhalten ist)
Bei klasischen Übertragungswegen die nicht auf dienste setzen die im web verbreitet sind, würde nur noch das bei mir integrierte verfahren anwenden. es ist sehr stabil udn erkennt auch übertragungsfehler. auserdem ist es schenll und kompakt, udn lässt sich noch kompackter gestalten. Zusätzlich ist es nicht komplett human-readable (was sicherheitstechnisch schonmal besser is, aber auch schlecht zum deven)
zu soap und xml sag ich jetzt mal lieber garnix.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 08.02.2013, 17:44 Titel: |
|
|
Ohne jetzt alles genau gelesen zu haben: in Battleship gibt es einen TSNE-basierten Dateiversand, eventuell hilft dir der Code ja. |
|
Nach oben |
|
 |
ichhalt
Anmeldungsdatum: 26.01.2013 Beiträge: 39
|
Verfasst am: 08.02.2013, 20:44 Titel: |
|
|
ThePuppetMaster hat Folgendes geschrieben: | Prinzipiel sollte ein Protokoll sehr logisch vorgehen. Dabei sollten Mechanissmen integriert werden, die erkennen ob die daten komplett eingetroffen sind, und ob die daten fehlerfrei übertragen wurden (was aber vernachlässigt werden kann, das solceh masnahmen bereits in TCP enthalten sind).
wenn man noch dafür sorgt, das die daten auch sauber strukturiert werden, dann ist das senden und das auslesen der empfangenden daten ebenfalls sehr einfach und übersichtlich.
ein beispiel / ne art vorlage ist hier zu finden:
http://ops.ath.cx/code?id=260
MfG
TPM |
Wo kriege ich die lib her die du in deiner vorlage benutzt? |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 08.02.2013, 20:45 Titel: |
|
|
Tja...das kommt davon, wenn man Routinen verwendet, die man nicht selber geschrieben hat
Du hast natürlich Recht, Puppet, ich habs verdaddelt.
Nun habe ich die Check_Nachricht dementsprechend geändert und nun funktioniert es auch.
Ach ja, da die Bilder als String versendet werden - wie groß darf ein String maximal sein?
Bei Win98 32000 Zeichen und ab XP 2 GB? |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 08.02.2013, 21:08 Titel: |
|
|
stevie1401 hat Folgendes geschrieben: | Bei Win98 32000 Zeichen und ab XP 2 GB? |
Bei Windows 98 liegt das Limit vermutlich irgendwo im dreistelligen Megabyte-Bereich, da es ja schon ab 512 MB RAM Schwierigkeiten beim Booten geben kann (siehe http://support.microsoft.com/kb/253912/de). Ein Speicherlimit von 32.000 Zeichen kann ich mir selbst unter Windows 98 nicht vorstellen. Das wären ja weniger als 32 kB und sogar weniger als eine vorzeichenbehaftete 16-Bit-Ganzzahl adressieren kann. Also das 32.000-Zeichen-Limit unter Windows 98 halte ich für ein Gerücht.
Ungefähr 2 GB dürften für Windows 2000 und aufwärts gelten. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|