Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 22:56

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Dateien versenden in C++

Discussion on Dateien versenden in C++ within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,876
Dateien versenden in C++

Mein problem liegt im Grunde nur darin, dass in der Datei auch "NUL"s enthalten sind. Da die meisten Funktionen Null aber als End Of String kennen, gab es teilweise schon Probleme beim auslesen der Datei, habe es dann aber so gelöst:
PHP Code:
    FILE pFile;
    
pFile fopen (file.c_str(), "rb" ); 
    
string buf;
    
char c;
    do
    {
        
cfgetc (pFile);
        if (!
feof(pFile)) buf+=c;
    } while (!
feof(pFile));
    
fclose (pFile); 
Dadurch wird zumindest die Datei ohne Probleme ausgelesen.
Problem scheint entweder das Empfangen oder das Schreiben zu machen.

Code :
PHP Code:
void Send_Data(char *ip,std::string file)
{
    
SOCKET sSocket;
    
int res ;
    
FILE pFile;
    
long lSize;
    
char buffer;
    
std::string buf;
    
size_t result;

    
pFile fopen (file.c_str(), "rb" );

    
char c;
    do
    {
        
cfgetc (pFile);
        if (!
feof(pFile)) buf+=c;
    } while (!
feof(pFile));

    
fclose (pFile);

    
SOCKADDR_IN service;
    
service.sin_family AF_INET;
    
service.sin_port htons12749 );
    
service.sin_addr.s_addr inet_addr(ip);

        
sSocket socketAF_INETSOCK_STREAM);
        
connectsSocket, (SOCKADDR *)(&service), sizeof(SOCKADDR_IN) );
        
sendsSocketbuf.c_str(), buf.length(), );
        
sendsSocket"[Ende]"6);

    
delete [] buffer;

PHP Code:
void Get_Data()
{
    
SOCKET sSocket;
    
SOCKET connectedSocket;
    
int res ;
    
FILE pFile;
    
long lSize;
    
char buffer;
    
std::string buf;
    
size_t result;
    
SOCKADDR_IN service;

    
sSocket socketAF_INETSOCK_STREAM);

    
buffer = (char*) malloc (sizeof(char)*100001);

    
memset(&service,0,sizeof(SOCKADDR_IN));
    
service.sin_family AF_INET;
    
service.sin_port htons12749 );
    
service.sin_addr.s_addr ADDR_ANY;

    
long rc=bind(sSocket,(SOCKADDR*)&service,sizeof(SOCKADDR_IN));
    
rc=listen(sSocket,10);
    
connectedSocket=accept(sSocket,NULL,NULL);

    
std::string temp,temp2;
    while (
1)
    {
        
temp2="";
        while (
temp2!="[Ende]")
        {
            
res recvconnectedSocketbuffer1000000);
            
temp2=buffer;
            if (
temp2=="[Ende]") break;
            else if (
temp2.find("[Ende]")!=std::string::npos)
            {
                break;
                
temp+=buffer;
                
temp=ReplaceAll(temp,"[Ende]","");
            }
            else 
temp+=buffer;
        }
        if (
res!=SOCKET_ERROR)
        {
            
pFile fopen ("C:\\piccom.bmp""wb" );
            
fwrite(buffer,1,res+1,pFile);
            
fclose (pFile);
        }
        else
        {
            
connectedSocket=accept(sSocket,NULL,NULL);
        }
    }
    
delete [] buffer;

WsaStartUp wird natürlich vor dem Aufruf der Funktionen gestartet.
Es wird auch etwas empfangen, aber teilweise fehlen Zeichen o.ä.

P.S.
Ich weiß, dass es kein "richtiges" C++ ist, da ich auch gleich fstream usw. benutzen könnte.
Mir ist fopen und ähnliches aber lieber.
Shadow992 is offline  
Old 11/05/2010, 15:27   #2


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
1. Nur die File Funktionen sehen 0 als Ende
Loesung: Stell den Mode auf Binary/nutze nicht die formatierenden Funktionen, sondern die, die einfach die Daten schreiben, ohne sie als Text zu interpretieren und formatieren oder nimm WinApi


Die Socket Funktionen beachten Nullen eh nicht.
Ich wuerde sagen, es liegt eher dran, dass du es dann in nen std string steckst.
Handelt es sich um ne reine Textdatei?

Dir ist fopen und aehnliches lieber? Ist fstream nicht aehnlich? :P
Naja ich finds bequehmer, abef ist nur meine Meinung ;O
MrSm!th is offline  
Old 11/05/2010, 18:29   #3
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,876
Quote:
Originally Posted by MrSm!th View Post
1. Nur die File Funktionen sehen 0 als Ende
Loesung: Stell den Mode auf Binary/nutze nicht die formatierenden Funktionen, sondern die, die einfach die Daten schreiben, ohne sie als Text zu interpretieren und formatieren oder nimm WinApi


Die Socket Funktionen beachten Nullen eh nicht.
Ich wuerde sagen, es liegt eher dran, dass du es dann in nen std string steckst.
Handelt es sich um ne reine Textdatei?

Dir ist fopen und aehnliches lieber? Ist fstream nicht aehnlich? :P
Naja ich finds bequehmer, abef ist nur meine Meinung ;O
Es können allerlei Programme sein, Bilder, Executeables usw.
Momentan habe ich mich auf Bilder vom Typen bmp beschränkt.
Um die Schnelligkeit des Datenverkehrs zu erhöhen, lasse ich die Dateien zuvor mit zlib comprimieren. Das comprimieren und decomprimieren klappt einwandfrei, das Auslesen jetzt auch.

fstream ist mir etwas ungewohnt, ich benutze auch lieber printf als cout.

Ich habe es jetzt mal versucht ohne std:string, aber jetzt kommt leider noch weniger an, habe ich vielleicht einen Denkfehler?

PHP Code:
void Get_Pic()
{
    
SOCKET sSocket;
    
SOCKET connectedSocket;
    
int res ;
    
FILE pFile;
    
long lSize;
    
char buffer;
    
std::string buf;
    
size_t result;
    
SOCKADDR_IN service;
    
sSocket socketAF_INETSOCK_STREAM);
    
    
buffer = (char*) malloc (sizeof(char)*100001);
    
memset(&service,0,sizeof(SOCKADDR_IN));
    
service.sin_family AF_INET;
    
service.sin_port htons12749 );
    
service.sin_addr.s_addr ADDR_ANY;

    
long rc=bind(sSocket,(SOCKADDR*)&service,sizeof(SOCKADDR_IN));
    
rc=listen(sSocket,10);
    
connectedSocket=accept(sSocket,NULL,NULL);
    while (
1)
    {
        
pFile =fopen("C:\\piccom.bmp""w+" );
        
fputs("",pFile);
        
fclose (pFile);
        while (
strcmp (buffer,"[Ende]" ) != && res>0)
        {
            
res recvconnectedSocketbuffer1000000);
            if (
strcmp (buffer,"[Ende]" ) == 0) break;
            else
            {
                
printf("%s",buffer);
                
pFile fopen ("C:\\piccom.bmp""a+" );
                for (
long i=0;i<sizeof(buffer);i++)
                    
fputc buffer[i] , pFile );
                
fclose (pFile);
                
strcpy(buffer,"");
            }
        }

    }

    
delete [] buffer;

Shadow992 is offline  
Old 11/05/2010, 23:13   #4


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Quote:
printf("%s",buffer);
Du wirst wohl kaum in nem Bild einen String finden, also warum printf mit %s? o.ô
Natürlich sucht das nach ner Null und interepretiert sie als Ende.

Zumindest die Ausgabe müsstest du anders schreiben.
Aber ich bin mir sicher, ich verstehe da etwas falsch, denn warum solltest du die Daten eines Bildes als String ausgeben.
Du sagtest doch, du willst ein Bild versenden oder nicht?

Warum behandelst du dann die empfangenen Daten wie einen String?

Nebenbei finde ich die Schleife nicht besonders schön.
Ungeachtet der funktionellen Richtigkeit:

Code:
res = recv( connectedSocket, buffer, 100000, 0);
if(strcmp (buffer,"[Ende]" ) != 0 && res>0)
{
        do
        {
                printf("%s",buffer);
                pFile = fopen ("C:\\piccom.bmp", "a+" );
                for (long i=0;i<sizeof(buffer);i++)
                    fputc ( buffer[i] , pFile );
                fclose (pFile);
                strcpy(buffer,"");
                res = recv( connectedSocket, buffer, 100000, 0);
        } while (strcmp (buffer,"[Ende]" ) != 0 && res>0);
}
Wäre schöner.

Ja, ich weiß, ich bin Perfektionist
MrSm!th is offline  
Old 11/06/2010, 04:28   #5

 
elite*gold: 150
Join Date: Apr 2007
Posts: 2,372
Received Thanks: 6,628
Code:
ifstream file;
file.open( pathtofile, ios_base::binary );
if(!file.is_open())
	// .....

file.seekg (0, ios::end);
int filesize = file.tellg();
file.seekg (0, ios::beg);

char *filebuffer = new char[filesize+1];
file.read( filebuffer, filesize );
file.close();
Hab mir jetzt nicht alles durchgelesen,
aber so sollte es klappen. Beim send aufruf dann halt
filesize als size parameter angeben.
wurstbrot123 is offline  
Old 11/06/2010, 10:20   #6
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,876
Quote:
Originally Posted by MrSm!th View Post
Du wirst wohl kaum in nem Bild einen String finden, also warum printf mit %s? o.ô
Natürlich sucht das nach ner Null und interepretiert sie als Ende.
Ok, das hatte ich mal wieder vergessen.
Quote:
Originally Posted by MrSm!th View Post
Zumindest die Ausgabe müsstest du anders schreiben.
Aber ich bin mir sicher, ich verstehe da etwas falsch, denn warum solltest du die Daten eines Bildes als String ausgeben.
Du sagtest doch, du willst ein Bild versenden oder nicht?

Warum behandelst du dann die empfangenen Daten wie einen String?
Ich lasse den String nur ausgeben, damit ich anschließend sehen kann ob und wieviel erfolgreich ankam. Es ist also mehr ein Test und wird dauerhaft nicht drinnen bleiben.
Quote:
Originally Posted by MrSm!th View Post
Nebenbei finde ich die Schleife nicht besonders schön.
Ungeachtet der funktionellen Richtigkeit:

Code:
res = recv( connectedSocket, buffer, 100000, 0);
if(strcmp (buffer,"[Ende]" ) != 0 && res>0)
{
        do
        {
                printf("%s",buffer);
                pFile = fopen ("C:\\piccom.bmp", "a+" );
                for (long i=0;i<sizeof(buffer);i++)
                    fputc ( buffer[i] , pFile );
                fclose (pFile);
                strcpy(buffer,"");
                res = recv( connectedSocket, buffer, 100000, 0);
        } while (strcmp (buffer,"[Ende]" ) != 0 && res>0);
}
Wäre schöner.

Ja, ich weiß, ich bin Perfektionist
Ja, dass du ein Perfektionist bist, ist mir schon oft aufgefallen, aber dafür funktioniert bei dir auch meistens alles.
Shadow992 is offline  
Old 11/06/2010, 12:42   #7


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Wenn du die Daten des Bildes ausgeben willst, um zu sehen, wie viele Bytes erfolgreich versendet wurden, musst du die Bytes in einen String konvertieren.
Sonst wird ja die erste Null im Bild als Null-Terminator interpretiert und du bekommst nur die Hälfte ausgegeben ;O

%X als (wie nennt man die Teile nochmal? o.ô) im sprintf format Parameter und das Byte/Dword wird in den dazugehörigen String konvertiert.
Soweit ich weiß, gibt es keinen für ein ganzes Byte Array, also müsstest du mit einer Schleife jedes Byte in den entsprechenden String konvertieren, sie aneinanderketten und das Ergebnis ausgeben


Quote:
Ja, dass du ein Perfektionist bist, ist mir schon oft aufgefallen, aber dafür funktioniert bei dir auch meistens alles.
Schön wärs, nach jedem erstellten Programm folgen 3 Tage nonstop Hardcore Debugging
(ok, danach funktionierts dann, also hast du evtl doch Recht, welcher nicht perfektionistische Mensch tut sich sowas nach jedem Programm an, nur um jeden noch so kleinen Fehler zu eliminieren )


Kleine Frage an wurstbrot
Quote:
char *filebuffer = new char[filesize+1];
file.read( filebuffer, filesize );
file.close();
new char[filesize+1]

So habe ich das bisher auch immer gemacht, aber mir ist gerade in den Sinn gekommen:
Man nutzt in diesem Falle ja das Char Array als Byte Array und nicht als String, schließlich würde es keinen Sinn machen, eine binäre Datei wie ein Bild als String zu interpretieren.
Ist dann das zusätzliche Byte für den Null-Terminator noch nötig? o.ô Eigentlich doch nicht oder doch?

Hat man ja wieder ein Byte gespart
MrSm!th is offline  
Reply


Similar Threads Similar Threads
C++ Dateien per mail versenden
11/03/2010 - C/C++ - 8 Replies
ich hab mir ein simples spiel erstellt, ab und zu tauchen auch da fehler auf. Damit ich die fehler schnell korrigieren kann soll die log.txt datei an mich per mail gesendet werden
C++ (Text-)Dateien hochladen/versenden
07/08/2010 - C/C++ - 53 Replies
Hallo erstmal! Ich bin auf der Suche nach einem Tutorial/ einem Beispielscript oder einfach einer kurzen erklärung, die mir dabei hilft Dateien hoch zu laden! Eine Erklärung hierzu: Ich hab einen Bot gemacht und wollte nun als Funktion einbauen, dass man Errors oder ähnliches an mich senden kann. Also der Bot erstellt bei errors automatisch eine Error.txt und diese würde ich gerne automatisch hochgeladen haben bzw. per E-mail an mich senden lassen!
Wie kann ich dateien aus Navicat Lite versenden ????
03/31/2010 - Metin2 Private Server - 0 Replies
Wie kann ich dateien aus Navicat Lite versenden ???? Gibt es ein Programm das das kann?
Dateien versenden
03/05/2010 - AutoIt - 1 Replies
Hi :D Ich habe eine eigene Homepage für Unsere Gilde gemacht. Und ich wollte ein Bot schreiben den sich die Gildenmitglieder downloaden können. Es stehen dort Termine z.b. "Clantraining am



All times are GMT +2. The time now is 22:56.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.