FTP через сокет пишет неправильный файл и другой размер c ++ - PullRequest
0 голосов
/ 23 апреля 2020

Итак, у меня был предыдущий вопрос здесь , и он помог мне понять и решить несколько вещей. Я все еще очень новичок в программировании сокетов и теперь попал в новую ошибку.

Когда я отправляю свой файл клиентской стороне, полученный файл всегда недействителен. (Я пытаюсь отправить почтовый файл). У меня также есть проблема с размером, так как размер исходного файла составляет 30 МБ, но клиент получает другой размер (разные байты). Это нормально или это должно быть исправлено?

вот мой код:

Сервер:

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.
}

Теперь на стороне клиента:

//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();

Таким образом, почти каждая очередь об отправке и recv говорит, что я не должен отправлять целый файл, потому что он может быть отправлен не в целом. но, отправив весь файл в al oop, я смог отправить файлы размером более 1 ГБ и правильно записать их на клиентскую сторону.

Я надеюсь, что это достаточно ясно. я сделал несколько модификаций, и я считаю, что это намного лучше, чем предыдущий, который я сделал по другому моему вопросу.

1 Ответ

0 голосов
/ 23 апреля 2020

Вы сделали 2 с половиной ошибки. Размер пакета на передачу обычно составляет 1024 байта буфера. Многие совершают ошибку, не подстраивая системные значения к этому значению. Ошибка в 1,5 раза заключается в том, что вы не сочли достаточно \ r \ n для обоих. Серверная часть пока (длина <= размер) ... </p>

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...