Dateien über Winsock versenden



  • Hallo,

    Es ist das 1. Mal, dass ich mich hier im Forum melde, da ich sonst immer über die Suchfunktion eine Lösung finden konnte. Nur dieses Mal leider nicht.

    Wie die Topic schon sagt, versuche ich über die Winsock Dateien zu versenden. Ich hab sogar ein tolles Beispiel gefunden im Internet, leider hat das Ding einen Haken, man kann nur Binär-Dateien versenden.

    So, ich hab dann hier meinen C-Beispel-Code mal gepostet und hoffe, dass mir jmd. einen Tipp geben kann, an welcher Stelle ich was ändern kann, damit ich z.B. Text-Dateien versendet werden können.

    #include <winsock2.h>
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    #pragma comment( lib, "ws2_32.lib" )
    
    typedef struct _NETFILEHEADER
    {
        unsigned long FileSize;
        char pFileName[256];
    } NETFILEHEADER;
    
    long SendFileToNet(const char *pFileName,
                       const char *pIP,
                       unsigned short Port)
    {
        FILE *pFile;
        unsigned long FileSize;
        char buffer[4096];
        NETFILEHEADER FileHeader;
        SOCKET sender;
        WSADATA wsa;
        SOCKADDR_IN addr;
        int addrlen = sizeof(SOCKADDR_IN);
    
        pFile = fopen(pFileName, "rb");
    
        if(!pFile) return 0;
    
        fseek(pFile, 0, SEEK_END);
        FileSize = ftell(pFile);
        fseek(pFile, 0, SEEK_SET);
    
        FileHeader.FileSize = FileSize;
        memset(FileHeader.pFileName, 0, 256);
        memcpy(FileHeader.pFileName, pFileName, strlen(pFileName));
    
        WSAStartup(MAKEWORD(2,0),&wsa);
    
        sender = socket(AF_INET, SOCK_STREAM, 0);
    
        memset(&addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(Port);
        addr.sin_addr.s_addr = inet_addr(pIP);
    
        connect(sender, (SOCKADDR*)&addr, addrlen);
    
        send(sender, (char*)&FileHeader, sizeof(NETFILEHEADER), 0);
    
        while(FileSize >= 4096)
        {
            fread(buffer, 4096, 1, pFile);
            send(sender, buffer, 4096, 0);
    
            FileSize -= 4096;
        }
    
        if(FileSize)
        {
            fread(buffer, FileSize, 0, pFile);
            send(sender, buffer, FileSize, 0);
        }
    
        closesocket(sender);
    
        fclose(pFile);
    
        WSACleanup();
    
        return FileSize;
    }
    
    long GetFileFromNet(unsigned short Port)
    {
        SOCKET server;
        SOCKET client;
        WSADATA wsa;
        SOCKADDR_IN addr;
        char buffer[4096];
        long rval;
        FILE *pFile;
        NETFILEHEADER FileHeader;
        long FileSize;
    
        int addrlen = sizeof(SOCKADDR_IN);
    
        WSAStartup(MAKEWORD(2,0),&wsa);
    
        server = socket(AF_INET, SOCK_STREAM, 0);
    
        memset(&addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(Port);
        addr.sin_addr.s_addr = INADDR_ANY;
        bind(server, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN));
    
        listen(server, 10);
    
        client = accept(server, (SOCKADDR*)&addr, &addrlen);
    
        recv(client, (char*)&FileHeader, sizeof(NETFILEHEADER), 0);
    
        FileSize = FileHeader.FileSize;
    
        pFile = fopen(FileHeader.pFileName, "wb");
    
        while(FileSize > 0)
        {
            rval = recv(client, buffer, 4096, 0);
            fwrite(buffer, rval, 1, pFile);
    
            FileSize -= rval;
        }
    
        fclose(pFile);
    
        closesocket(client);
        closesocket(server);
    
        WSACleanup();
    
        return FileHeader.FileSize;
    }
    
    void main(void)
    {
        //SendFileToNet("net.cpp", "192.168.0.1", 80);
        //GetFileFromNet(80);
    }
    

    P.S. Ich benutze kein C++ und besitze nur die Kostenlose C-IDE "Pelles C".

    mfg Chris



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Man sieht sofort dass diese Funktionen datei binärisch behandelt.

    pFile = fopen(pFileName, "rb");
    
    fseek(pFile, 0, SEEK_END);
        FileSize = ftell(pFile);
        fseek(pFile, 0, SEEK_SET);
    

    theoretisch muss es aber auch text-dateien übertragen können, weil sie ja auch binärisch aufgebaut 😃



  • Ich danke erst einmal, dass jemand geantwortet hat auf diesen Beitrag.

    Aber ich habe natürlich noch an diesem Code weitere Tests gemacht und festgestellt, dass es glaub ich sinnlos ist mit diesem Code weiterzuarbeiten, da ich merkwürdigerweise nur Bilddateien und Anwendungen versenden kann. Z.B. Archive & Textdateien kommen nicht an. 😞



  • Ich wollte mich bloß nochmal melden, da ich einen einfacheren Weg gefunden habe Dateien über die Winsock zu übertragen:

    (Datei von Server zu Client)

    Server:

    #include <Mswsock.h>
    
    HANDLE hFile;
    
    ...
    
    hFile = CreateFile("Datei.exe",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL); 
    
    TransmitFile(Socket, hFile, 0, 0, NULL, NULL, TF_DISCONNECT);
    
    CloseHandle(hFile);
    
    ...
    

    Client:

    #include <winsock2.h>
    
    int rc;
    FILE *f;
    
    ...
    
    f = fopen("Datei.exe", "wb");
    do
    {
    rc = recv(s, buffer, sizeof(1026), 0);
    buffer[rc] = '\0';
    fwrite(buffer, rc, 1, f);
    }
    while(rc!=0);
    fclose(f);
    
    ...
    

    Ich hoffe ich hab das jetzt einigermaßen komplett geschrieben.

    Nachteil: Nach der Übertragung wird die Verbindung getrennt, aber wenn
    das Flag "TF_DISCONNECT" weggelassen wird, dann bleibt der Server hängen.



  • Mein Tipp: besorg dir einen Hexeditor und schau dir die Datei an die gesendet wurde und die Datei die empfangen wurde - vergleiche sie und stelle fest wo das Problem liegt: z. B. es kommt kein einziges Byte der Datei an, die Dateigröße stimmt aber nur die ersten 4096 Bytes sind ungleich 0 - der Rest ist 0, usw. - so kann man am einfachsten den Fehler finden - BTW: du solltest alle Dateien sind binär verschicken, egal ob Text oder nicht - das macht keinen Unterschied



  • hallo,

    eine frage zu TransmitFile(...)
    kann man auch in ner schleife die ganze zeit abfragen wie viele
    bytes schon versendet wurden? um den fortschritt in %
    anzuzeigen z.B.

    oder müsste man dazu eine extra verbindung zum Client aufbauen damit
    der Client diese Informationen sendet?

    danke



  • In einer Server-Anwendung braucht man doch keine Fortschrittsanzeige. 🤡



  • aber was ist wenn man was zum server sendet und im Client
    eine Forschrittsanzeige möchte?

    🙂



  • dann muss man den tranfer selbst coden. 🙂



  • genau das musste ich nämlich machen^^
    dachte schon hier gäb es einen einfacheren weg *puh*

    😃


Anmelden zum Antworten