Protokollentwicklung
-
Klar doch (o;
-
junix schrieb:
UDP: Ja aber bei UDP erfolgt doch auch kein Acknowledge oder? KLar kommt es zu lags... aber wenn bei 1000 Paketen / s 1 verloren geht ist das nicht die Welt.
Äh apropos Mechanismus wo jeder das zu empfangen hat: War da nicht was mit der Broadcast-Adresse die man sich aus der Netzmaske ausrechnen kann?
-junix
Nein, mir geht es um einen Datei Transfer wo ein Server von mehreren anderen Clients gleichzeitig ein File annehmen können.
-
Zero01 schrieb:
Nein, mir geht es um einen Datei Transfer wo ein Server von mehreren anderen Clients gleichzeitig ein File annehmen können.
das geht auch. jeder teilnehmer kann eine vielzahl von verbindungen quasi-parallel bedienen. für dateitransfer würde ich aber immer tcp und nicht udp nehmen
-
So habs nun auch geschaft die Dateien erfolgreich zu versenden und empfangen. Mein ursprüngliches Problem war, dass ich wärend einer langweiligen Vorlesung programmiert habe und um das ganze zu testen, mit meinem PC zuhause kommuniziert hatte und meine Firewall verrückt spielte, weiss zwar nicht wieso, aber ist eh ein scheiss Ding. Ich habe es nun so gelösst, dass ich zuerst vom Client aus die Grösse der Datei als String an den Server sende, dann am Client mitteile, dass dieser bereit ist und lese anschliessend die Daten ein.
@Zero01 hast du das mit dem empfangen nun auch hin gekriegt? Ich habe im Post von dir über neues Fenster zur Laufzeit erstellen gelesen, dass dein Chat Progi ein Webcam Support besitzt. Nun wollte ich dich noch fragen, wie du die Bilder der Webcam ausliest?
-
Habe soeben in der FAQ das Beispiel Progi zur Webcam gefunden.
-
Jop ,hab gestern Nacht Filme mit 800 Mb und mehr vom Rechner zum Laptop gesendet.
Ich habe das Problem das beim Client sowie Server die CPU Auslastung auf 100% springt und alles bis auf den File Transfer blockiert wird. Ich bastel noch etwas und poste den code später@ Net:
Zero01 schrieb:
Wie kommt ihr darauf einen Filetransfer auf UDP aufzubauen wenn man TCP zur Verfügung hat ? Das schreit ja förmlich danach

Ich würde mich hüten mit UDP Dateien zu versenden. ich benutze UDP für den Chat und zur Steuerung des Client/Server Sockets

Beispiel: FTP Port 20 Authent und Control und Port 21 Daten
-
Hatte das gleiche Problem wie du Zero01. Beim Server, welcher die Daten empfängt, konnte ich es einfach lösen indem ich. Ich hatte eine Schleife in der er gefangen war, bis er alle Daten erhalten hatte. Habe jetzt die nötigen Variabeln in der Klasse als Privat deklariert und die Schleife herausgenommen, jetzt wird die Funktion OnClientRead einfach mehrmals aufgerufen, bis er alle Daten hat und speichert das File anschliessend ab. Bei Client, welcher die Datei sendet habe ich es noch nicht gelösst. Wenn ich etwas Zeit habe werde ich es mal mit einem Timer versuchen, damit ich ihn nicht in der Schleife hangen lasse, bis alles raus ist.
-
Die Lösung über den Timer hört sich Interessant an da man noch nen Slider einbauen kann wo man die geschwindigkeit regulieren kann. In einem event darf man ohnehin keine Schleife verwenden. Momentan habe ich das Problem das ich den FileStream global deklariert habe und ihn nicht freigeben kann.
kein Plan wie ich die initialisierung des Filestreams ausserhalb des onRead Events machen soll und ihn wieder freizugeben. Perfekt wäre noch das für jede IP von der Dateien übertragen werden einen expliziten FileStream anzulegen. Ich habe beim Server eine TStringListe wo IP + Dateiname + Dateigröße von jedem Client gespeichert wird.
Eine weitere StringListe speichert die übertragenen bytes und wird pro OnRead entsprechend hochgezählt um zu erkennen wann der File zu ende geladen ist um den Stream wieder freizugeben.Weiß da jemand Rat wie das zu realisieren ist oder bin ich auf dem richtigen Weg

Aber die Sache mit dem globalen Deklarieren und nicht mehr freigeben können nervt total, da muss es doch ne andere Möglichkeit geben wie man explizit für jede Client IP einen Filestream vor dem Senden anlegt und danch wieder freigibt ?
-
Hi Zero01,
Ich hatte mit dem FileStream auch Probleme. Hatte es dann mal mit einem MemoryStream versucht und es hat geklappt.
-
Ok, ich versuche es jetzt auch mal mit dem Memory Stream. Würdest du mir dabei helfen ?
Bis jetzt habe ich folgendes:Global:
TMemoryStream * Stream = new TMemoryStream();Senden
TMemoryStream *mem = new TMemoryStream(); mem->LoadFromFile(Form1->OpenDialog1->FileName); mem->Seek(0,0); Form1->ClientSocket1->Socket->SendStream(mem); delete mem;Empfangen OnReadEvent
int Buffer = 1024; int filesize = StrToInt(FileSize(filelist->Values[Socket->RemoteAddress])); String filename = FileName(filelist->Values[Socket->RemoteAddress]); BYTE *Buffer_BYTEp = new BYTE[Buffer]; Stream->Position = Stream->Size; Socket->ReceiveBuf(Buffer_BYTEp, Buffer); Stream->Write(Buffer_BYTEp, Buffer); delete [] Buffer_BYTEp; if (Stream->Size == filesize) { Stream->SaveToFile(Form2->Label1->Caption + "\\" + filename); delete Stream; }Wie hast du das Empfangen gelöst ? Momentan wird das Programm so übel abgeschossen das man noch nicht mal mehr ne Fehlerausgabe hat

So wie es aussieht steigt er schon beim Senden aus
-
Debuggen und schauen wo genau der Abschuss passiert wär doch mal ne Option?
-junix
-
ich bekomme beim senden eine Acess violation at Address 000000000. Wenn ich das delete auskommentiere tritt dieser Fehler nicht ein, bin total ratlos

-
Hm, wie esch scheint, haben wir wieder einmal das selbe Problem. Anfangs lief bei mir das Progi, also dass heisst einmal, und jetzt habe ich auch diesen Fehler, allerdings nicht immer bei der selben Adresse. Auch wenn ich das delete auskommentiere, tritt dieser Fehler manchmal auf.
-
Man sollte ja auch die mit "new" erstellen Instanzen von Objekten prüfen ob sie denn wirklich erstellt wurden bevor man sie benutzt (o;
-junix
-
ich bin zwar nicht so der borland-freak aber so'n tcp-stack arbeitet immer asynchron. wenn man dem den buffer unterm hintern weglöscht kann's schon crashen. diese borland-klassen haben doch sicher 'ne möglichkeit den status des sockets abzufragen bzw. ob der noch am senden ist etc. erst wenn alles wech ist sollte man die buffer löschen, die datei schliessen usw.
-
Eigentümer des Stream, der als Parameter an SendStream übergeben wird, wird das Windows-Socket-Objekt. Das Windows-Socket-Objekt gibt den Stream nach erfolgter Verarbeitung frei. Versuchen Sie nicht, den Stream, nachdem er als Parameter übergeben wurde, freizugeben.
So, jetzt bekomm ich keine Access Violation mehr beim Senden. Jedoch wird die Datei beim erstellen immer zu groß

Senden
mem = new TMemoryStream(); mem->LoadFromFile(Form1->OpenDialog1->FileName); mem->Seek(0,0); if (mem) Form1->ClientSocket1->Socket->SendStream(mem);Empfangen
int Buffer = 1024; int filesize = StrToInt(FileSize(filelist->Values[Socket->RemoteAddress])); String filename = FileName(filelist->Values[Socket->RemoteAddress]); BYTE *Buffer_BYTEp = new BYTE[Buffer]; Stream->Position = Stream->Size; Socket->ReceiveBuf(Buffer_BYTEp, Buffer); Stream->Write(Buffer_BYTEp, Buffer); delete [] Buffer_BYTEp; if (Stream->Size >= filesize) Stream->SaveToFile(Form2->Label1->Caption + "\\" + filename);Wenn das OnReceive Ereignis einmal ausgelöst wird ist die Datei 1024byte groß und beim zweiten mal 2048..........
Die Quelldatei war aber 1147 bytes groß 
Wie hast du das empfangen gelöst ?
-
Was willst du denn mit dem "if (mem)" da noch?
Ausserdem würde ich nochmal genau überlegen, ob ReceiveBuf() wirklich immer die ganze Buffersize empfängt oder nicht. Als kleiner Tip: Es muss einen Grund geben, wieso ReceiveBuf() das zurückliefert was es zurückliefert (o;
Ansonsten ist das Verhalten aber völlig logisch... Denk nochmal genau darüber nach.
-junix
-
Jaaaaa Junix mein Freund, pro Aufruf subtrahiere ich 1024 byte von filesize solange bis nur noch ein Rest kleiner 1024 bleibt und dies die letzte Puffergröße ist

<= Held vom Erdbeerfeld

-
Heisst das jetzt, dein Problem ist gelöst?
Übrigens: Ich persönlich fänds erheblich eleganter den Rückgabewert von ReceiveBuf() auszuwerten. Es verringert die Dateifehler (o;
-junix
[edit]Ausserdem kümmer dich mal um ordentliche Kommentare und wichtiger: Anständige und aussagekräftige Variablennamen!!![/edit]
-
Das habe ich schon gemacht. Muss zum Fliegerarzt und melde mich später wieder !