Winsock Datein
-
Schwammkopf schrieb:
ich habs mit fwrite() versucht.
Sollte auch funktionieren, wenn mans richtig macht.
-
rb und wb angegeben?
-
... rc=recv(s,buffer,64, 0); fstream datei("datei.doc", ios::in |ios::binary | ios::beg); fwrite(buf,1,64, datei); ...
-
server.cpp //Datei senden ifstream file ("Datei.doc", ios::out | ios::binary |ios::ate); size = file.tellg(); file.seekg(0, ios::beg); buffer = new char [size]; file.read (buffer, size); rc=send(connectedSocket,buffer,256, 0);client.cpp //Datei empfangen while(rc!=SOCKET_ERROR) { rc=recv(s,buf,256, 0); } FILE* newWord; newWord = fopen("Datei.doc", "wb"); ifstream Word ("Datei.doc", ios::in | ios::out |ios::binary); fwrite(buf,1,sizeof(buf), newWord);Nach dem Senden kommt bei mir immer die Fehlermeldung "Server hat die Verbindung getrennt"
Die Datei wird zwar vollständig empfangen, aber sie kann nicht in Word geöffnet werden(Man muss die Codierung auswählen).
Im Dokument kommt nur das : [][][][] (mehrere Seiten)Hat jemand eine Lösung ?
Gruss Sheldor
-
Hat jemand den Fehler schon gefunden ?
Edit: Die Zeile ifstream ... braucht es beim Client gar nicht oder ?Gruss Sheldor
-
bevor ich hier iwas angucke:
du prüfst, ob send alles gesendet hat und recv alles empfangen hat?(mist, jz hab ich doch hingeguckt und iwie verspür ich den zwang, doch was dazu zu schreiben...)
buffer = new char [size]; rc=send(connectedSocket,buffer,256, 0);sieht nicht so aus, als ob es richtig wäre...
char* buffer = new char[size]; int rc=0; for(int i(0); i < size; i += rc) { rc = send(connectedSocket, buffer+i, size-i, 0); if(rc > 0) continue; if(rc == 0) /* verbindung geschlossen oder so - exception*/ if(rc == SOCKET_ERROR) /* guck wsalasterror - dann wirf einfach ne execption */ }while(rc!=SOCKET_ERROR) { rc=recv(s,buf,256, 0); } FILE* newWord; newWord = fopen("Datei.doc", "wb"); ifstream Word ("Datei.doc", ios::in | ios::out |ios::binary); fwrite(buf,1,sizeof(buf), newWord);das hier sieht erst recht komisch aus...
irgendwie so, als ob du gar keine ahnung hättest, was da passiert... :S/*wir kennen die größe nicht - du musst dir also nen protokoll ausdenken, was dir die größe übermittelt und dann die datei/... schickt frecherweise nehm ich mal an, es gibt eine variable 'size', in der die richtige größe gespeichert ist...*/ /*dateiname könntest du entweder auch übermitteln oder erfinden - endung entweder festlegen oder auch mit übermitteln. ich nehm auch hier wieder an: dateiname steht in einer variablen 'file_name'*/ char* buffer = new char[size]; int rc=0; for(int i(0); i < size; i += rc) { rc = recv(s, buffer+i, size-i, 0); if(rc > 0) continue; if(rc == 0) /* ... */ if(rc == SOCKET_ERROR) /* ... */ } std::ofstream recv_file(file_name, std::ios::out | std::ios::binary); recv_file.write(buffer, size);ACHTUNG: es fehlt jeweils ein delete[]. das ist zwar nicht notwendig, um das Programm zum funktionieren zu bringen, aber mehr als empfehlenswert

ich würde das senden/empfangen und das datei auslesen/schreiben jeweils in eine eigene funktion packen und statt der rohen zeiger smart-ptr verwenden - vrmtl in beiden fällen scoped ptr.
noch nen kleineres achtung:
dateien können größer sein als der wertebereich eines integers - auf den meisten systemen wird diese variante nur mit dateien bis zu 2^31 -1 byte gehen. also ab 2GB kannst du das vergessen - allerdings wird eh schon ab vll 1 GB(zumindest auf 32bit systemen) bad_alloc geworfen werden.es ist halt auch nicht die perfekte lösung - aber sollte dir zeigen, wie es richtig wäre...
ne bessere lösung bekommst du vll, wenn du zeigst, dass du dich mit dem code auseinander gesetzt hast und ich gerad wieder zeiut und lust hab
bb
-
Ist jetzt Sheldor == Schwammkopf?

@Sheldor,
Dein Code ist der grösste Unsinn den es gibt. Du liest falsch ein, du versendest falsch, du speicherst falsch. Der Code ist von A bis Z falsch.Zum Beispiel liest man mit
std::istreamund dem Flagios::inein. Womöglich ist dein Stream fehlerhaft und du liest gar nichts sinnvolles ein. In deinem Puffer steht dann nur Unsinn. Beim übermitteln, übermittelst du plötzlich konstant 256 Bytes. Wieso? Was ist, wenn das File kleiner oder grösser ist? Da kannst du sogar undefiniertes Verhalten erzeugen. Zudem prüfst du nicht nach, wieviel tatsächlich gesendet wurde. Du prüft überhaupt auf gar keine Fehler.
Beim lesen liest du einfach immer 256 Bytes und überschreibst sie wieder, bis einSOCKET_ERRORkommt. Somit hast du am Ende nur die letzten 256 Bytes, sofernbufwirklich diese Grösse hat. Deristreamist völlig verkehrt, es müssteostreammitios::outsein. Obsizeof(buf)die richtige Grösse zurückgibt ist auch fraglich. Wennbufzum Beispiel ein Zeiger ist, dann wäre dies auch falsch. Schliessen tust du das File nicht? Und Fehler prüfen tust du ja sowieso nicht.Was soll man da sagen ausser: Lern zuerst die Grundlagen!
Ich weiss nicht, ob du nicht sogar zuerst die C++ Grundlagen lernen solltest, zumindest sieht es sehr danach aus. Falls du meinst, dass du die C++ Grundlagen kannst, dann gäbe es hier noch ein gutes C Tutorial zu WinSockets:
http://www.c-worker.ch/tuts.phpGrüssli
-
unskilled schrieb:
bevor ich hier iwas angucke:
du prüfst, ob send alles gesendet hat und recv alles empfangen hat?(mist, jz hab ich doch hingeguckt und iwie verspür ich den zwang, doch was dazu zu schreiben...)
buffer = new char [size]; rc=send(connectedSocket,buffer,256, 0);sieht nicht so aus, als ob es richtig wäre...
char* buffer = new char[size]; int rc=0; for(int i(0); i < size; i += rc) { rc = send(connectedSocket, buffer+i, size-i, 0); if(rc > 0) continue; if(rc == 0) /* verbindung geschlossen oder so - exception*/ if(rc == SOCKET_ERROR) /* guck wsalasterror - dann wirf einfach ne execption */ }while(rc!=SOCKET_ERROR) { rc=recv(s,buf,256, 0); } FILE* newWord; newWord = fopen("Datei.doc", "wb"); ifstream Word ("Datei.doc", ios::in | ios::out |ios::binary); fwrite(buf,1,sizeof(buf), newWord);das hier sieht erst recht komisch aus...
irgendwie so, als ob du gar keine ahnung hättest, was da passiert... :S/*wir kennen die größe nicht - du musst dir also nen protokoll ausdenken, was dir die größe übermittelt und dann die datei/... schickt frecherweise nehm ich mal an, es gibt eine variable 'size', in der die richtige größe gespeichert ist...*/ /*dateiname könntest du entweder auch übermitteln oder erfinden - endung entweder festlegen oder auch mit übermitteln. ich nehm auch hier wieder an: dateiname steht in einer variablen 'file_name'*/ char* buffer = new char[size]; int rc=0; for(int i(0); i < size; i += rc) { rc = recv(s, buffer+i, size-i, 0); if(rc > 0) continue; if(rc == 0) /* ... */ if(rc == SOCKET_ERROR) /* ... */ } std::ofstream recv_file(file_name, std::ios::out | std::ios::binary); recv_file.write(buffer, size);ACHTUNG: es fehlt jeweils ein delete[]. das ist zwar nicht notwendig, um das Programm zum funktionieren zu bringen, aber mehr als empfehlenswert

ich würde das senden/empfangen und das datei auslesen/schreiben jeweils in eine eigene funktion packen und statt der rohen zeiger smart-ptr verwenden - vrmtl in beiden fällen scoped ptr.
noch nen kleineres achtung:
dateien können größer sein als der wertebereich eines integers - auf den meisten systemen wird diese variante nur mit dateien bis zu 2^31 -1 byte gehen. also ab 2GB kannst du das vergessen - allerdings wird eh schon ab vll 1 GB(zumindest auf 32bit systemen) bad_alloc geworfen werden.es ist halt auch nicht die perfekte lösung - aber sollte dir zeigen, wie es richtig wäre...
ne bessere lösung bekommst du vll, wenn du zeigst, dass du dich mit dem code auseinander gesetzt hast und ich gerad wieder zeiut und lust hab
bb
Ich habe nicht den ganzen Code hinzugefügt, deshalb war Delete[] und das senden der Grösse der Datei nicht dabei

Vielen Dank für deinen Geposteten Code !!! Werd mich später mit ihm auseinandersetzen
Ist jetzt Sheldor == Schwammkopf?
[code]Nein

Was soll man da sagen ausser: Lern zuerst die Grundlagen!
Ich weiss nicht, ob du nicht sogar zuerst die C++ Grundlagen lernen solltest, zumindest sieht es sehr danach aus. Falls du meinst, dass du die C++ Grundlagen kannst, dann gäbe es hier noch ein gutes C Tutorial zu WinSockets:
http://www.c-worker.ch/tuts.phpDieses Tutorial habe ich angeschaut, aber über das versenden von Binären Datein (.exe, .odt usw.) gab es nichts.
Die Grundlagen kann ich glaube ich auch

Danke für eure Antworten
Gruss Sheldor
-
Sheldor schrieb:
Die Grundlagen kann ich glaube ich auch

dein geposteter code sieht nicht so aus, als ob du die c++-grundlagen kennst.
aber das du die winsock-grundlagen nicht kennst, dafür würde ich meine hand ins feuer legen...bb
-
unskilled schrieb:
Sheldor schrieb:
Die Grundlagen kann ich glaube ich auch

dein geposteter code sieht nicht so aus, als ob du die c++-grundlagen kennst.
aber das du die winsock-grundlagen nicht kennst, dafür würde ich meine hand ins feuer legen...bb
Mit Winsock habe ich gerade erst angefangen ...

Es ist ein bisschen verwirrend
-
Sheldor schrieb:
Dravere schrieb:
Ist jetzt Sheldor == Schwammkopf?

Nein

Also missbrauchst du einfach einen Thread von jemand anderen für deine Zwecke?
Sheldor schrieb:
Dieses Tutorial habe ich angeschaut, aber über das versenden von Binären Datein (.exe, .odt usw.) gab es nichts.
Du solltest das Tutorial nicht nur anschauen, sondern es auch durchmachen und daraus was lernen. Wo siehst du den unterschied zwischen dem Senden von Bytes (z.B. Text) und dem Senden von Bytes (z.B. Files)? Der Rest betrifft C++ Grundlagen, also das Einlesen und Schreiben von Files.
Sheldor schrieb:
Die Grundlagen kann ich glaube ich auch
Sieht wirklich nicht so aus. Schon nur die falsche Verwendung von
std::istreamlässt kein fundiertes Wissen vermuten. Aber auch der Umgang mit den Puffern und auch sonstiges im Code, lässt eher auf ein zusammenschnipseln schliessen, als dass da jemand mit Überlegung und Wissen rangegangen ist.Grüssli
-
[quote="Dravere"]
Sheldor schrieb:
Dravere schrieb:
Ist jetzt Sheldor == Schwammkopf?

Nein

Also missbrauchst du einfach einen Thread von jemand anderen für deine Zwecke?
[\quote]Hätte ich einen neuen Thread eröffnen sollen ?
Ich werde noch einmal die Grundlagen anschauen, danke für deine Hilfe.
Sieht wirklich nicht so aus. Schon nur die falsche Verwendung von std::istream
Meinst du ifstream ?
Gruss Sheldor
-
sheldor1 schrieb:
Hätte ich einen neuen Thread eröffnen sollen ?
Es sind die gleichen Themen ... hmmm ... ich weiss nicht. Ist in meinen Augen ein Grenzfall. Ich hätte wahrscheinlich zuerst mal gewartet, was hier rausgekommen wäre. Die Gefahr besteht halt, dass es unterschiedliche Probleme sind, wieso "es nicht geht". Im allgemeinen benötigt jeder eine eigene Behandlung.
sheldor1 schrieb:
Sieht wirklich nicht so aus. Schon nur die falsche Verwendung von std::istream
Meinst du ifstream?
Ja, das f hat sich unerlaubt von der Truppe entfernt

Grüssli