Frage

Ich bin der Aufbau ein Server-Client-Programms mit c und mit etwas problen Wtih sendina einem ganzen Datei mit send () und recv () Funktion. Ich brauche die ganze Datei mit diesen aber all diese Funktionen tun, ist eine Zeichenfolge senden zu senden. Das Hauptproblem ist mit den exe oder anderen binären formen Daten senden. Sollte ich htons oder htonl func? Ich weiß nicht, wie diejenigen entlang diese zu verwenden, wie ich bin nur ein noob.

Ich bin mit diesem stecken und lieben Ihre Hilfe. Dank !!

Hier ist die Server-Seite recv Funktion ::

if (socket_type != SOCK_DGRAM)
    {

            fi = fopen (final,"wb");
            retval = recv(msgsock, recv_buf, strlen(recv_buf), 0);
            /*recv_buf[retval] = '\0';
            fprintf (fi,"%s",recv_buf);*/

            int i;
            i=atoi(recv_buf);
            char *q;
            q=(char *)malloc(i*sizeof(char));
            retval = recv(msgsock, q, strlen(q), 0);
            //printf ("%s",q);
            fwrite(q,i,1,fi);
            fclose(fi);

    }
    else
    {
        retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen);
        printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr));
        printf ("SOCK_DGRAM");
    }

    if (retval == SOCKET_ERROR)
    {
        fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError());
        closesocket(msgsock);
        //continue;
    }
    else
        printf("Server: recv() is OK.\n");

    if (retval == 0)
    {
        printf("Server: Client closed connection.\n");
        closesocket(msgsock);
            //continue;
    }
    printf("Server: Received %d bytes, data from client\n", retval);

Die Client-Seite zu senden Funktion :::

void kommando_senden () {     int bytesent;     FILE * file_out;     // file_out = fopen (file_path, "rb");     char str_all [100000]; // flag [30] = "end";

///////////////////////getsize//////////////
char fsize[5];
int filesize;
file_out = fopen(file_path, "rb");
fseek(file_out, 0, SEEK_END);
filesize = ftell(file_out);
rewind (file_out);
itoa (filesize,fsize,10);
/////////////////////////////////////////////
send (ConnectSocket, fsize, strlen (fsize), 0);

char *r = (char *)malloc (filesize * sizeof(char));

fread(r,filesize,1,file_out);
bytesent = send( ConnectSocket, r, strlen(r), 0 );
printf("\nClient: Bytes sent: %ld\n", bytesent);
fclose (file_out);

/*while (fscanf(file_out,"%s",&str_all) != EOF)
{
    bytesent = send( ConnectSocket, str_all, strlen(str_all), 0 );
    printf("\nClient: Bytes sent: %ld\n", bytesent);
    //Sleep(500);
}*/

/*printf("%s",flag);
send( ConnectSocket, flag, strlen(flag), 0 );*/
WSACleanup();
//return 0;
}
War es hilfreich?

Lösung

Sie müssen diese Funktionalität selbst implementieren, oder eine Bibliothek verwenden, die so tut. send(2) sendet nur einen rohen Byte-Puffer. Wenn Sie eine Datei senden möchten, müssen Sie irgendeine Art von Protokoll verwenden , dass sowohl der Client als auch der Server verstehen.

Das einfachste mögliche Protokoll könnte den Client hat die Dateinamen senden, um die Länge der Datei, und dann die RAW-Datei-Daten. Zum Beispiel (Fehler aus Gründen der Übersichtlichkeit weggelassen Prüfung):

// Server:
const char *filename = ...;
uint32_t filenameLen = strlen(filename);
uint32_t filenameLenNet = htonl(filenameLen);
send(fd, &filenameLenNet, sizeof(filenameLenNet), 0);
send(fd, filename, filenameLen, 0);

// You should probably use a 64-bit file length; also, for large files, you
// don't want to read the entire file into memory, you should just stream it
// from disk to network in reasonably-sized chunks.
const void *fileData = ...;
uint32_t fileLen = ...;
uint32_t fileLenNet = htonl(fileLen);
send(fd, &fileLenNet, sizeof(fileLenNet), 0);
send(fd, fileData, fileLen, 0);

// Client:
char *filename;
uint32_t filenameLen;
recv(fd, &filenameLen, sizeof(filenameLen), 0);
filenameLen = ntohl(filenameLen);
filename = malloc(filenameLen + 1);
recv(fd, filename, filenameLen, 0);
filename[filenameLen] = 0;
uint32_t fileLen;
recv(fd, &fileLen, sizeof(fileLen), 0);
fileLen = ntohl(fileLen);
void *fileData = malloc(fileLen);
recv(fd, fileData, fileLen, 0);
// Write file Data to the output file.  Again, for large files, it would be
// better to stream it in in chunks instead of reading it all in at once.

Auch vorsichtig sein, teilweise sendet / empfängt. Stellen Sie sicher, überprüfen Sie die Rückgabewerte von send und recv, da sie (und tun) oft nur senden oder eine Teilmenge der Daten erhalten Sie Vorsatz oder zu senden und empfangen. Wenn das passiert, müssen Sie durch das Zurücksenden oder rereceiving in einer Schleife erholen, bis Sie alle Daten verarbeitet haben Sie bestimmt oder ein Fehler auftritt.

Als Alternative Ihr eigenes Protokoll zu verwenden, können Sie ein vorhandenes Protokoll mit einer Bibliothek so verwenden, wie libftp oder libcurl .

Andere Tipps

send () keine Zeichenfolge senden, sendet sie ein Byte-Array. Sie erstellen Ihre Puffer, füllen Sie es, den Puffer senden und die Anzahl der Bytes in es passieren zu senden () und von dort aus.

Je nach Betriebssystem eingeschaltet sind, kann es sein, ein sendfile Befehl; aber es ist nicht arbeiten portably über verschiedene Betriebssysteme gewährleistet. Die meisten tragbaren Weg ist, einfach read() die Datei in in Stücke in einen Puffer, und dann write() es (oder send() es aus, wenn Sie eine Steckdose verwenden, obwohl write() sollte gut zu) arbeiten.

Siehe geht im wesentlichen die gleiche Sache.

Was Sie tun müssen, ist Ihre Daten in mehreren Stücken zu senden, ein Klumpen zu einem Zeitpunkt. Also, im Wesentlichen lesen Sie Ihre Datei N Bytes zu einer Zeit, in einen Puffer und send () diejenigen N-Bytes.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top