Dateien über Winsock versenden



  • wenn du schon std::string benutz kannst du doch auch die einbauten funktionen benutzen siehe http://cplus.kompf.de/artikel/strings.html
    warum machst du abort nicht boolisch ?

    probiert es mal so
    [cpp]
    while (strcmp(abort, "no") == 0)
    {
    string apart = explode('|', buf, count);

    if(apart.compare("") != 0) // oder apart.size() > 0
    {
    part3 += apart;
    ++count;
    }
    else
    abort = "yes";

    }

    MessageBox(NULL, part3.c_str(), "info", MB_OK);
    [/cpp]



  • Geil! Es klappt endlich!
    Vielen Dank für die schnelle Antwort und den Codeschnipsel!
    Nach dem letzten Zeichen erscheint in der Messagebox zwar noch ein bisschen Müll - aber das bekomm´ ich bestimmt auch noch hin 😃 🙄

    THX Maxime

    Achja - bevor ich´s vergesse:
    VIELEN DANK AN ALLE, DIE AUF MEINE FRAGEN GEANTWORTET HABEN!
    IHR HABT MIR SEHR WEITERGEHOLFEN! 👍



  • 😡 ...Jaja... der Filetransfer klappt - aber leider nur bei kleinen Textdateien 😞 Bei Gif oder PNG-Dateien sieht das ganze dann in etwa so aus:

    ‰PNG
    
     ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýýÝÝÝQ   ±   °œ P› ÀsB ¶   €         ýýýý @  @ `Q@ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý    ±   1      Àœ $~B             ýýýýÿÿÿÿÁ
    ÍÍÿÿÿÿÁ
    ÍÍÿÿÿÿÁ
    ÍÍÿÿÿÿ
    

    😞
    Ich seh´ mich echt schon in ein paar Wochen mit ´nem FTP-Server hantieren 😞 😕



  • Hi!
    Ich könnte die Datei allerdings noch "binär" auslesen und sie in Einzelteilen versenden - aber ich habe
    noch keine Ahnung wie ich das anstellen soll 🙄

    crazychicken (alias "Maxime")

    PS:
    Kennt vielleicht jemand von euch ein gutes Tutorial über "Dateien über Winsock versenden"? Ich bin jetzt nämlich bei meinem Projekt so ziemlich mit meinem Latein am Ende 🙄



  • HANDLE fileHandle;
    DWORD fileSize;
    DWORD bytesRead;
    char *sendeBuffer;
    
    // Datei öffnen:
    fileHandle=CreateFile("test.gif",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
    
    // Dateigröße holen:
    fileSize=GetFileSize(fileHandle,NULL);
    
    // Speicher für die Datei und die Längenangabe holen:
    sendeBuffer=(char*)malloc( fileSize+sizeof(DWORD) );
    
    // Länge in den sendeBuffer kopieren:
    memcpy(sendeBuffer,(void*)&fileSize,sizeof(DWORD));
    
    // Datei hinter die Längenangabe in den sendeBuffer einlesen:
    ReadFile(fHandle,sendeBuffer+sizeof(DWORD),fileSize,&bytesRead,NULL);
    
    // DateiHandle schließen:
    CloseHandle(fileHandle);
    
    // Daten über Winsock senden:
    send(zielSocket,sendeBuffer,(fileSize+sizeof(DWORD)),0);
    
    // Speicher freigeben:
    free(sendeBuffer);
    

    So ungefähr würde ich das senden machen, also quasi erst senden wieviele Bytes kommen (einfach einen DWORD schicken) und direkt danach eben die komplette Datei binär rübersenden...



  • Vielen Dank für das Codebeispiel!
    Werde es (sobald ich Zeit habe) mal so ausprobieren.
    Vielleicht klappt´s ja dann 👍

    PS: Man könnte doch mal ein Beispiel der Dateiübertragung über Winsock in die FAQ´s stellen, oder? (Ist nur ein Vorschlag ;))

    crazychicken 🙂



  • Hi geeky!
    Habe dein Codebeispiel gleich´ mal in mein Projekt eingebunden und getestet:

    (Sender)

    HANDLE file;
    	char * buffer;
    	DWORD FileSize;
    	DWORD BytesRead;
    
    	file = CreateFile("test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    	FileSize = GetFileSize(file, NULL);
    
    	buffer = (char*)malloc( FileSize+sizeof(DWORD) );
    	memcpy(buffer,(void*)&FileSize,sizeof(DWORD)); 
    
    	ReadFile(file, buffer+sizeof(DWORD), FileSize, &BytesRead, NULL);
    	CloseHandle(file);
    
    	send(connectedSocket, buffer, (FileSize+sizeof(DWORD)), 0);
    
    	free(buffer);
    

    Empfänger:

    char * check = "no"; char buf[40000]; 
    
    			while (check == "no")
    			{
    				rc=recv(s, buf, 40000, 0);
    				buf[rc]='\0';
    
    				if(strcmp(buf, "") != 0)
    				{check = "yes";}
    			}
    
    			MessageBox(NULL, buf, "info", MB_OK);
    

    test.txt - Datei:

    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    

    - doch leider werden nur NULL-Zeichen übertragen 😞
    Weis einer von euch, woran das liegen könnte?
    Der Code ist doch völlig richtig, oder nicht?

    Vielen Dank!
    carzychicken 🙂



  • (check == "no")

    Das kann schonmal nicht richtig sein. Stringvergleiche macht man mit lstrcmp



  • Danke!
    Hab es jetzt auf

    while (strcmp(check, "no") == 0)
    

    geändert - doch es werden von der Datei leider immer noch nur NULL-Zeichen übertragen.

    Wenn ich eine andere Datei zur Übertragung verwende, kommt der Dateicode komischerweise nur in Einzelteilen beim Server an.

    Ich versteh´ jetzt irgendwie gar nichts mehr... 🙄

    [EDIT]:
    Habe gerade mit einer MessageBox herausgefunden, dass die Datei gar nicht falsch empfangen, sondern schon falsch gesendet wird! 😮 Könnte vielleicht einer von euch nochmal über den Code gucken? Wäre euch dafür super dankbar!





  • Hi!
    Es werden 154 bytes gesendet und der Wert von WSAGetLastError() ist 0.



  • // test_sendfile.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    #include "winsock2.h"
    #include "stdlib.h"
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
     	SOCKET zielSock;
    	SOCKET listenSock;
    	SOCKET accSock;
    	sockaddr_in sai;
    	WSADATA wsa;
    
    	HANDLE fileHandle;
    	DWORD fileSize;
    	DWORD bytesRead;
    	DWORD bytesWritten;
    	char *sendeBuffer;
    	char *recvBuffer;
    	int recvBufferPos;
    	int recvLen;
    
    	char temp[50];
    
    	// Winsock init:
    	WSAStartup(MAKEWORD(2,2),&wsa);
    
    	// Sockets initialisieren:
    	listenSock=socket(AF_INET,SOCK_STREAM,0);	// Socket das auf Verbindungen wartet
    	zielSock=socket(AF_INET,SOCK_STREAM,0);	// Socket mit dem verbunden wird
    
    	// Der empfangen-Teil soll als Server laufen:
    	sai.sin_addr.s_addr=inet_addr("127.0.0.1");
    	sai.sin_family=AF_INET;
    	sai.sin_port=htons(5000);	
    	bind(listenSock,(sockaddr*)&sai,sizeof(sockaddr_in));
    	listen(listenSock,SOMAXCONN);
    
    	// DATEI SENDEN
    	//////////////////////////////////////////////	
    
    	// Datei öffnen:
    	fileHandle=CreateFile("Readme.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
    	if (fileHandle==INVALID_HANDLE_VALUE)
    	{
    		OutputDebugString("Datei konnte nicht geöffnet werden!");
    		return 0;
    	}
    
    	// Dateigröße holen:
    	fileSize=GetFileSize(fileHandle,NULL);
    
    	wsprintf(temp,"Ich sende eine %i Bytes große Datei!",fileSize);
    	MessageBox(0,temp,"lol",0);
    
    	// Speicher für die Datei und die Längenangabe holen:
    	sendeBuffer=(char*)malloc( fileSize+sizeof(DWORD) );
    
    	// Länge in den sendeBuffer kopieren:
    	memcpy(sendeBuffer,(void*)&fileSize,sizeof(DWORD));
    
    	// Datei hinter die Längenangabe in den sendeBuffer einlesen:
    	ReadFile(fileHandle,sendeBuffer+sizeof(DWORD),fileSize,&bytesRead,NULL);
    
    	// DateiHandle schließen:
    	CloseHandle(fileHandle);
    
    	// Mit Zielrechner verbinden:
    	connect(zielSock,(sockaddr*)&sai,sizeof(sockaddr_in));
    
    	// Daten über Winsock senden:
    	send(zielSock,sendeBuffer,(fileSize+sizeof(DWORD)),0);
    
    	// Verbindung mit Zielrechner trennen:
    	closesocket(zielSock);
    
    	// Speicher freigeben:
    	free(sendeBuffer);
    
    	// Datei empfangen
    	/////////////////////////////////////////
    
    	// Verbindung annehmen:
    	accSock=accept(listenSock,NULL,NULL);
    	if (accSock==INVALID_SOCKET)
    	{
    		return 0;
    	}
    
    	OutputDebugString("socket angenommen!");
    
    	// Ein bisschen Speicher reservieren:
    	recvBuffer=(char*)malloc( sizeof(DWORD)*2 );
    
    	// Die ersten sizeof(DWORD) Bytes empfangen:
    	recvBufferPos=0;
    	while (recvBufferPos<sizeof(DWORD))
    	{
    		recvLen=recv(accSock,recvBuffer+recvBufferPos,1,0);
    		if (recvLen==SOCKET_ERROR)
    		{
    			OutputDebugString("recv() meldet Fehler!");
    		}
    		recvBufferPos=recvBufferPos+recvLen;
    	}
    
    	// Datei Größe einlesen:
    	memcpy(&fileSize,recvBuffer,sizeof(DWORD));
    
    	wsprintf(temp,"Es kommt eine %i Bytes große Datei!",fileSize);
    	MessageBox(0,temp,"lol",0);
    
    	// Datei zum speichern öffnen:
    	fileHandle=CreateFile("ReadmeNew.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
    	if (fileHandle==INVALID_HANDLE_VALUE)
    	{
    		OutputDebugString("Datei konnte nicht geöffnet werden!");
    		return 0;
    	}
    
    	// Alten Speicher freigeben und passenden Speicher für die Datei holen:
    	free(recvBuffer);
    	recvBuffer=(char*)malloc(fileSize);
    
    	// Datei komplett empfangen:
    	recvBufferPos=0;
    	while (recvBufferPos<fileSize)
    	{
    		recvLen=recv(accSock,recvBuffer+recvBufferPos,1,0);
    		if (recvLen==SOCKET_ERROR)
    		{
    			OutputDebugString("recv() meldet Fehler!");
    			recvLen=0;
    		}
    		recvBufferPos=recvBufferPos+recvLen;
    	}
    
    	// Datei schreiben:
    	WriteFile(fileHandle,recvBuffer,fileSize,&bytesWritten,NULL);
    
    	// Datei schließen:
    	CloseHandle(fileHandle);
    
    	// Empfangsspeicher freigeben:
    	free(recvBuffer);
    
    	// Winsock shutdown:
    	WSACleanup();
    
    	return 0;
    }
    


  • Vielen Dank für den kompletten Code, geeky!
    So etwas findet man hier nicht oft! 👍

    Ich frage mich z.Zt. nur, warum ich den sendeBuffer in keiner MessageBox darstellen kann. 😕

    PS: Ich wusste gar nicht, dass du in Meschede wohnst! - Wohne nämlich in Winterberg 😉

    THX! 🙂

    [EDIT]:
    Ach... scheiß Messageboxen - hauptsache es FUNKTIONIERT!!!!!! 🙂 🙂 🙂 🙂
    Vielen Dank an euch alle - und besonders an Geeky!!!! 👍



  • Du kannst nicht einfach den Inhalt einer Binärdatei in einer MessageBox ausgeben, da ja auch 0-Zeichen enthalten sein können - außerdem wirst du z.B. mit dem Inhalt einer PNG-Datei in Textform wenig anfangen können 😉



  • hi!
    wie kann ich da so so einen dialog machen der mich auswählen lässt welche datei ich senden möchte????
    natürlich müsste dann ja auch der dateiname vor dem senden der datei übertragen werden, wie macht man das am besten?

    bye



  • ja beim empfänger möchte ich so einen dialog machen speichern unter.... so wie halt bei icq!!!
    bitte um hilfe!

    bye



  • #include "stdafx.h" 
    #include <winsock2.h> 
    #include <stdlib.h>
    
    #pragma comment( lib, "ws2_32.lib" )
    
    int APIENTRY WinMain(HINSTANCE hInstance, 
                         HINSTANCE hPrevInstance, 
                         LPSTR     lpCmdLine, 
                         int       nCmdShow) 
    { 
        SOCKET zielSock; 
        SOCKET listenSock; 
        SOCKET accSock; 
        sockaddr_in sai; 
        WSADATA wsa; 
    
        HANDLE fileHandle; 
        DWORD fileSize; 
        DWORD bytesRead; 
        DWORD bytesWritten; 
        char *sendeBuffer; 
        char *recvBuffer; 
        int recvBufferPos; 
        int recvLen; 
    
        char temp[50]; 
    
        // Winsock init: 
        WSAStartup(MAKEWORD(2,2),&wsa); 
    
        // Sockets initialisieren: 
        listenSock=socket(AF_INET,SOCK_STREAM,0);    // Socket das auf Verbindungen wartet 
        zielSock=socket(AF_INET,SOCK_STREAM,0);    // Socket mit dem verbunden wird 
    
        // Der empfangen-Teil soll als Server laufen: 
        sai.sin_addr.s_addr=inet_addr("192.168.0.1"); 
        sai.sin_family=AF_INET; 
        sai.sin_port=htons(5000);    
        bind(listenSock,(sockaddr*)&sai,sizeof(sockaddr_in)); 
        listen(listenSock,SOMAXCONN); 
    
        // DATEI SENDEN 
        //////////////////////////////////////////////    
    
        // Datei öffnen: 
    
    			OPENFILENAME ofn;
    
    			ZeroMemory((void *)&ofn, sizeof(ofn));
    
    			ofn.hwndOwner = hDlg;
    			ofn.lStructSize = sizeof(ofn);
    			ofn.hInstance = NULL;
    			ofn.nMaxCustFilter = 0;
    			ofn.nFilterIndex = 0;
    			ofn.lpstrFile = (char *)&SendFileName;
    			ofn.nMaxFile = MAX_PATH;
    			ofn.lpstrFileTitle = NULL;
    			ofn.nMaxFileTitle = MAX_PATH;
    			ofn.lpstrFilter = "All Files (*.*)\0*.*\0";
    			ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT;
    
    			if(!GetOpenFileName(&ofn))	
    				return(0);
    
        // Dateigröße holen: 
        fileSize=ofn.lStructSize;
    
        wsprintf(temp,"Ich sende eine %i Bytes große Datei!",fileSize); 
        MessageBox(0,temp,"lol",0); 
    
        // Speicher für die Datei und die Längenangabe holen: 
        sendeBuffer=(char*)malloc( fileSize+sizeof(DWORD) ); 
    
        // Länge in den sendeBuffer kopieren: 
        memcpy(sendeBuffer,(void*)&fileSize,sizeof(DWORD)); 
    
        // Datei hinter die Längenangabe in den sendeBuffer einlesen: 
        ReadFile(fileHandle,sendeBuffer+sizeof(DWORD),fileSize,&bytesRead,NULL); 
    
        // DateiHandle schließen: 
        CloseHandle(fileHandle); 
    
        // Mit Zielrechner verbinden: 
        connect(zielSock,(sockaddr*)&sai,sizeof(sockaddr_in)); 
    
        // Daten über Winsock senden: 
        send(zielSock,sendeBuffer,(fileSize+sizeof(DWORD)),0); 
    
        // Verbindung mit Zielrechner trennen: 
        closesocket(zielSock); 
    
        // Speicher freigeben: 
        free(sendeBuffer);
    
        // Winsock shutdown: 
        WSACleanup(); 
    
        return 0; 
    }
    

    warum funzt das mittn fileHandle nicht??;-(

    cu



  • Ich kann nirgends etwas entdecken, wo du die Datei öffnest - außerdem ist deine fileSize-Ermittlung völliger Schwachsinn, da du nur die Größe der OPENFILENAME-Struktur ausliest 😉



  • werd ich no mal durchdenken....aber frage, wie ich muss ja vorher die den dateinamen übertragen zum client bevor ich die datei sende? ist die dateigröße a noch von bedeutung?

    cu



  • #include "stdafx.h" 
    #include <winsock2.h> 
    #include <stdlib.h>
    
    #pragma comment( lib, "ws2_32.lib" )
    
    int APIENTRY WinMain(HINSTANCE hInstance, 
                         HINSTANCE hPrevInstance, 
                         LPSTR     lpCmdLine, 
                         int       nCmdShow) 
    { 
        SOCKET zielSock; 
        SOCKET listenSock; 
        SOCKET accSock; 
        sockaddr_in sai; 
        WSADATA wsa; 
    
        HANDLE fileHandle; 
        DWORD fileSize; 
        DWORD bytesRead; 
        DWORD bytesWritten; 
        char *sendeBuffer; 
        char *recvBuffer; 
        int recvBufferPos; 
        int recvLen; 
    
        char temp[50]; 
    
        // Winsock init: 
        WSAStartup(MAKEWORD(2,2),&wsa); 
    
        // Sockets initialisieren: 
        listenSock=socket(AF_INET,SOCK_STREAM,0);    // Socket das auf Verbindungen wartet 
        zielSock=socket(AF_INET,SOCK_STREAM,0);      // Socket mit dem verbunden wird 
    
        // Der empfangen-Teil soll als Server laufen: 
        sai.sin_addr.s_addr=inet_addr("192.168.0.1"); 
        sai.sin_family=AF_INET; 
        sai.sin_port=htons(5000);    
        bind(listenSock,(sockaddr*)&sai,sizeof(sockaddr_in)); 
        listen(listenSock,SOMAXCONN); 
    
        // DATEI SENDEN 
        //////////////////////////////////////////////    
    
        // Datei öffnen: 
    	OPENFILENAME ofn;
        char szFileName[MAX_PATH] = "";
    	char szFileTitle[MAX_PATH] = "";
    
        ZeroMemory(&ofn, sizeof(ofn));
    
        ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
        ofn.hwndOwner = NULL;
        ofn.lpstrFilter = "Text Files All Files (*.*)\0*.*\0";
        ofn.lpstrFileTitle = szFileTitle;
        ofn.nMaxFileTitle = MAX_PATH;
    	ofn.lpstrFile = szFileName;
        ofn.nMaxFile = MAX_PATH;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        //ofn.lpstrDefExt = "txt";
    
        if(GetOpenFileName(&ofn))
        {
            // Do something usefull with the filename stored in szFileName 
    		MessageBox(0, szFileTitle, "Info", 0);
    
            fileHandle=CreateFile(szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); 
    
    		if (fileHandle==INVALID_HANDLE_VALUE) 
    		{ 
    			OutputDebugString("Datei konnte nicht geöffnet werden!"); 
    			return 0; 
    		} 
    
    		// Dateigröße holen: 
    		fileSize=GetFileSize(fileHandle,NULL); 
    
    		wsprintf(temp,"Ich sende eine %i Bytes große Datei!",fileSize); 
    		MessageBox(0,temp,"lol",0); 
    
    		// Speicher für die Datei und die Längenangabe holen: 
    		sendeBuffer=(char*)malloc( fileSize+sizeof(DWORD) ); 
    
    		// Länge in den sendeBuffer kopieren: 
    		memcpy(sendeBuffer,(void*)&fileSize,sizeof(DWORD)); 
    
    		// Datei hinter die Längenangabe in den sendeBuffer einlesen: 
    		ReadFile(fileHandle,sendeBuffer+sizeof(DWORD),fileSize,&bytesRead,NULL); 
    
    		// DateiHandle schließen: 
    		CloseHandle(fileHandle); 
    
    		// Mit Zielrechner verbinden: 
    		connect(zielSock,(sockaddr*)&sai,sizeof(sockaddr_in)); 
    
    		// Daten über Winsock senden: 
    		send(zielSock,sendeBuffer,(fileSize+sizeof(DWORD)),0); 
    
    		// Verbindung mit Zielrechner trennen: 
    		closesocket(zielSock); 
    
    		// Speicher freigeben: 
    		free(sendeBuffer);
        }
    

    ok ich hab nun soweit mittn file open dialog;-) sollte man nicht vorher beim übertragen der datei den filetitle übertragen????

    cu


Anmelden zum Antworten