Hi i have been making two programs: one that sends a file's filebuf made into a char*, and another that receives that and writes it to a file. They're like exe sending programs. I can send the char* and write it onto the console using cout.write(), but when I try to copy it onto a file, it will only be like 3 bytes in size while the original file is 500kb. How would I write it correctly? I don't want to show all of my code because that would take up space, and most of it is irrelevant. I will just show the sending, receiving, and writing.

Sending:

ifstream in(FileName,ios::binary);

if (in)
    {
    filebuf *pbuf;
    pbuf = in.rdbuf();
    long size;
    size = pbuf->pubseekoff(0,ios::end,ios::in);
    char * buffer;
    buffer = new char[size];
    pbuf->pubseekpos(0,ios::in);
    pbuf->sgetn(buffer,size);
    if (send(sClient, buffer, strlen(buffer), 0) != SOCKET_ERROR)
    {
    cout << "\nSent file successfully!";
    }
    else
    {
    cout << "\nError sending file!\n";
    }
    }

Receiving and Writing:

char cClientMessage[500000];
recv(sClient, cClientMessage, 499999, 0);

ofstream out(TempFileName.c_str(), ios::binary);
string ConfirmString;
    if (out)
    {
    out.write(cClientMessage, strlen(cClientMessage));
    ConfirmString = "Successfully copied file! New file name is ";
    ConfirmString += TempFileName;
    out.close();
    }
    else
    {
    ConfirmString = "Error copying file!";
    }  
    send(sClient, ConfirmString.c_str(), ConfirmString.length(), 0);
    }

Recommended Answers

All 3 Replies

> send(sClient, buffer, strlen(buffer), 0)
1. You already have the size of the buffer in your size variable.
2. strlen() will return at the first \0 in your binary data, or the first \0 in some random location beyond the end of your data
3. send doesn't guarantee to send all the data in a single call.

totalSent = 0;
numSent = 0;
toBeSent = size;
while ( toBeSent > 0 ) {
    numSent = send ( sClient, &buffer[totalSent], toBeSent, 0);
    if ( numSent == 0 ) { return "socket closed"; }
    if ( numSent == SOCKET_ERROR ) { return "error"; }
    totalSent += numSent;
    toBeSent -= numSent;
}

Similarly, the recv() does NOT guarantee to reassemble the whole message in one call, that's your job using a similar kind of loop.

Remember, it's binary data, so ALL your strlen() calls are wrong.

Thanks, I'll revise my code and try it.

That works perfectly! Thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.