user12401635
user12401635

Reputation:

FTP over socket writing wrong file and different size c++

So i had a previous question here, and it helped me understand and solve few things. i am still very new to socket programming and now got into a new bug.

as i send my file to the client side, the file received is always invalid. ( i am trying to send a zip file). i also have a problem with the size as the size of the original file is 30Mb but client receive a different size( bytes different). is it normal or it should be fixed?

here is my code:

Server:

char buf[4096];

/*Sending files and recvieing test...*/
std::string message = "Welcome to the server :)";
ZeroMemory(buf, 4096);

if (send(clientsocket, message.c_str(), 4096, 0) > 0) {
    std::cout << "Sent to client successfully" << std::endl;
}

if (recv(clientsocket, buf, sizeof(buf), 0)) {

    std::cout << "Recv: " << std::string(buf, 0, 4096)<<std::endl;

}

// File opening and sending.
std::ifstream file("C:\\test.zip", std::ios::in | std::ios::binary | std::ios::ate);

file.seekg(0, file.end);// get file size
unsigned long size = file.tellg();
file.seekg(0);
char* buffer = new char[size]; // buffer or memblock to hold the file.
file.read(buffer, size);// write to the buffer.
file.close();

//Conver the size into string to send it throu socket.
std::string siz;
std::stringstream str;
str << size;
str >> siz;



// send the file size and receive a message from client.
int byteSent = 0;
if (byteSent = send(clientsocket, siz.c_str(), 10, 0)) {
    std::cout << byteSent << std::endl;
    if (recv(clientsocket, buf, 4009, 0)) {
        std::cout << std::string(buf, 0, 4096)<<std::endl;
    }
}

/*File sending FTP*/

byteSent = 0;
int length=0;

while (length < size) {

    if (byteSent = send(clientsocket, buffer, 1021 , 0)) { // tried few different sizes to send and client still got different size.

        length += byteSent;
    }
    else
    {
        std::cout << "Connectionlost, Error: " << WSAGetLastError()<<std::endl;
    }
    std::cout << "Sending: " << length << " Size: " << size - length << "Left to send" << std::endl; // keep track of how many bytes was sent.
}

Now on client side:

//Send and Recvied from server:

char buff[4096];
std::string message = "Recv is working";
int bytesR = 0;
int byteSent = 0;
int tot = 0;
ZeroMemory(buff, 4096);

if (bytesR = recv(server, buff, 4096, 0) > 0) {

    std::cout << "Server >> " << std::string(buff, 0, 4096) << std::endl;
    if (byteSent = send(server, message.c_str(), message.size(), 0) > 0) {
        std::cout << "Sent successfully to server." << std::endl;

    }
}
else {
    std::cout << "No connection";
}
int sizz;



//Receiving size
std::string siz;
int len = 0;
char bufsize[200];

if (bytesR = recv(server, bufsize, sizeof(bufsize), 0)) {

    std::cout << "Bytes Recvied: " << bytesR << std::endl;
    siz = std::string(bufsize, 0, 4096);
    std::cout << "File size recv: " << siz << std::endl;
     sizz = std::stoi(siz);

    std::cout << "Size recved to int: " << sizz << std::endl;

    message = "Recvied size of file : " + std::string(buff, 0, 4096);
    if (send(server, message.c_str(), message.size(), 0)) {

    }
}

//Create the file after receiving the size.
std::ofstream file("test.zip", std::ofstream::binary);
char* filebuf = new char[sizz];

bytesR = 0;
int recvied = 0;


while (recvied < sizz) {
    bytesR = recv(server, filebuf, 1021, 0);
    if (bytesR > 0) {

        file.write(filebuf, bytesR); // write the block of file received based on how many bytes received.
        recvied += bytesR;
        std::cout << "Reciveing...  " << recvied << "   out of:  " << sizz << std::endl;// keeping track of received bytes.
    }
    else
    {
        std::cout << "Connecton lost, Error: " << WSAGetLastError() << std::endl;
        break;
    }

}

file.close();

So, almost every quetion about sending and recv says that i shouldnt send a whole file coz it might not be sent as awhole. but by sending the whole file in a loop, i was able to send files over 1gb of size and write it correctly to the client side.

i hope its clear enough. i did few modifications and i believed this is a lot better than the previous one i did on my other question.

Upvotes: 1

Views: 185

Answers (1)

John Connor
John Connor

Reputation: 1

You made 2 and a half mistakes. The packet size per transfer is normally 1024 bytes buffer. Many make the mistake of not adjusting the system values ​​to this value. The 1.5 x error is that you have not considered the \r\n enough for both. Server side while (length <= size) ...

Good luck!

Upvotes: 0

Related Questions