Probleme beim senden der Datei !

cesupa

Erfahrenes Mitglied
Hallo,

ich hab mal versucht größere Dateien über eine Socketverbindung unter Windows zu senden.
Das hat anfangs auch ganz gut geklappt jedoch hat mein Server irgendwann aufgehört Daten zu empfangen und hat dann einige Zeit später weitergemacht. Mein Serverprogramm hat anscheinend eine Pause oder sowas gemacht. Diese Pause hat beim client natürlich einen Fehler ausgelöst und WSAGetLastError() gab 10014 aus. Was hat das denn zu bedeuten ?

Hier mein Code vom Client:

Code:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <fstream>
#include "socket_init.h"
using namespace std;
SOCKET c;
ifstream quelle;
int main(int argc, char *argv[])
{
int len;
char buf[50000];
char databuf[10000];

quelle.open("pp.zip",ios::in | ios::binary); //Datei oeffnen

quelle.seekg(0L,ios::end); //Groesse der Datei feststellen
len=quelle.tellg(); //in int len schreiben
quelle.seekg(0L,ios::beg); //zurück an Anfang der Datei

cout<<len<<endl; //Groesse ausgeben
Sleep(2000); //kurze Pause damit man sich die groesse anschauen kann

quelle.read(databuf,len); //Datei einlesen

c=client_init(18,"127.0.0.1",AF_INET,SOCK_STREAM,0,false); //Socket erstellen

for (int i=0;i<len;++i)
{
senden(c,(char*)&databuf[i],1,0,false); //jedes einzelne Zeichen senden
cout<<i<<endl; //an welcher Stelle ist mein prog ?
}
quelle.close(); //Datei schließen
system("PAUSE");
return EXIT_SUCCESS;
}

Ich hab mir für die Verbindung eine Klasse geschrieben, wenn ihr sie sehen wollt dan postet es einfach, aber ich glaub nicht das es an der Klasse hängt.

Hier der Quellcode des Servers:
Code:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <fstream>
#include "socket_init.h"
using namespace std;
SOCKET c;
ofstream ziel;
int main(int argc, char *argv[])
{
char buf[500000];
char databuf[10000];

ziel.open("test1.zip",ios::out | ios::binary); //Datei oeffnen

c=server_init(18,AF_INET,SOCK_STREAM,0,false); //Server Socket erstellen
int i;
while(empfangen(c,buf,1,0,false)>0) //Daten empfangen
{
i++;
cout<<i<<endl;
//strcat(databuf,buf);
ziel.write(buf,1); //empfangene Daten in Datei schreiben
}

ziel.close(); //Datei schließen
system("PAUSE");
return EXIT_SUCCESS;
}

Mit kleineren Dateien funktioniert das Prog aber einwandfrei !

MfG
cesupa
 
- der WSA fehler kommt wenn man einen ungültigen Datenpopinter an die Sendefunktion übergibt.. da wär es vielleicht doch interessant zu sehen wie das bei dir aussieht (in deiner klasse)

also wenn ich dein prog richtig verstanden habe, dann ist mir noch folgendes aufgefallen:

- du solltest die rückgabewerte von send() auf jedenfall überprüfen: es kann passieren das send() weniger gesendet hat als man angegeben hat - das muss man abfangen

- jedes zeichen einzeln zu senden ist nicht grad sehr gut (eher sehr schlecht !), wenn es nicht unbedingt sein muss, denn so produzierst du immensen overhead bei der TCP verbindung, das kann bei grossen Dateien schon eklig werden - verwende eine puffer in etwa der maximalen grösse des tcp pakets
 
Ich hab mir auch schon gedacht das es nicht gut ist jedes Zeichen einzeln einzulesen.
Hab das auch mal mit nem Buffer versucht hat aber nicht funktioniert. Kann mir jemand ein Beispielcode geben, wie ich ein sehr großes char-Array (in dem meine Daten sind) in viele kleine char-Arrays teilen kann und dann über die leitung versende ?
Wäre echt nett von euch.

Gruß
cesupa
 
mmh das erste was mir einfällt: guck dir mal std::stringstream an:

pseudocode würde dann ungefähr so aussehen:

Code:
stringstream = chararray
while( stringstream ) {
  Intcheck = send( socket, stringstream, PUFFERGRÖSSE, 0);
  if ( intcheck <= 0 )
    ERROR
}

Wenn du nur Dateien verschickst dann nimm am besten gleich einen Filestream
-> guck dir dazu mal die Funktion fopen() an.
wenn du dir anguckst wie stringstreams funktionieren verstehst du bestimmt was ich meine :)
 
Hey vielen Dank, jetzt bleibt der server wenigstens nicht mehr hängen, jedoch hab ich mal versucht eine 38-stellige Zeichenkette zu versenden. Das mit dem senden hat einwandfrei funktioniert, aber das Problem ist, dass er nicht mehr aufhört zu senden. Woran kann das denn nun liegen ? :rolleyes:

Danke aber schon mal für deine antworten.

cesupa
 
nun wenn du direkt aus der datei mit einem filestream sendest dann bleibt er immer gültig - dann muss du für die abbruchbedingung auf endoffile (ich glaub funkion: filestream.feof()) testen.

ansonsten kann das viele ursachen haben: was sendet er denn wenn er nicht aufhört ? ungültige daten? oder das letzte zeichen immer wieder ?
 
Hab mir jetzt mal das gesendete angeschaut und bemerkt das die letzten Zeichen alle gleich sind. Habs jetzt auch mal so hier versucht:

Code:
while(!stream1.eof())
    {
              check=senden(c,(char*)&stream1,255,0,false);    
              if(check<=0)
              cout<<"FEHLER";
              
                  }

hat aber auch nicht funktioniert, der hat noch immer die gleichen Zeichen am ende gehabt nur so ungefähr in der Mitte sah es anders aus. Die letzten Zeichen waren diese: ¬¬¬¬¬¬ und inder Mitte wiederholten sich diese Zeichen ein paar mal: ¸  8 à Ð =Ð=¼D¬

Ich hab null ahnung woran das liegen könnte.

Gruß
cesupa
 
mmh naja vielleichts liegts ja an der typenumwandlung
ich weis zwar nicht wie deine senden() funktion aussieht,

aber probiers doch mal mit nem Puffer vorm senden...
also ungefähr so (also beim mir funktionierts ;) ):
Code:
nCount = fread(pBuffer, sizeof(char) , nBuffSize , pFileStream);
und sende dann denn Buffer... ich hab dazu einfach nen charpointer benutzt...
 
Zuletzt bearbeitet:
Sag mal geht das ganze auch in c++ ?
Ich habs jetzt mal in C versucht jedoch kommt dann imer ein Fehler von Windows.

Code:
int senddatas(SOCKET s,char datei[256])
{
    FILE* quelle;
    int len;
    char buf[50000];
    char databuf[10000];
    fopen(datei,"r");
    
    fseek(quelle,0L,SEEK_END); //Groesse der Datei feststellen
    len=ftell(quelle);         //in int len schreiben
    fseek(quelle,0L,SEEK_SET); //zurück an Anfang der Datei
//    */
    cout<<len<<endl;  
    Sleep(2000);         //Groesse ausgeben
      //Datei einlesen
    //c=client_init(18,"127.0.0.1",AF_INET,SOCK_STREAM,0,false); //Socket erstellen
    for (int i=0;i<len;++i)
    {
        fread(databuf,sizeof(char),50,quelle);
                                       senden(s,(char*)&databuf,50,0,false); //jedes einzelne Zeichen senden
                      cout<<i<<endl;
                        }
                 fclose(quelle);       //Datei schließen
                 return 0;
                 }

Vielleicht habe ich ja im Code was falsch, was ich auch ganz stark vermute. :rolleyes:

Trotzdem Danke !

cesupa
 
Zurück