c++ - 套接字上的FTP写入错误的文件和不同大小的C++

标签 c++ sockets tcp

所以我之前有一个问题here,它帮助我理解和解决了几件事。
我对套接字编程还是很陌生,现在遇到了一个新的错误。

当我将文件发送到客户端时,收到的文件始终无效。 (我正在尝试发送一个zip文件)。我也有大小问题,因为原始文件的大小为30Mb,但客户端收到的大小不同(字节不同)。这是正常的还是应该解决?

这是我的代码:

服务器:

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

因此,关于发送和接收的几乎所有疑问都说我不应该发送整个文件,因为它可能不会整体发送。但是通过循环发送整个文件,我能够发送超过1gb的文件并将其正确写入客户端。

我希望它足够清楚。我做了很少的修改,我相信这比我在另一个问题上所做的修改要好得多。

最佳答案

您犯了两个半错误。每次传输的数据包大小通常为1024字节缓冲区。许多人犯了不将系统值调整为该值的错误。 1.5 x错误是您没有足够地考虑\r\n两者。服务器端while(长度<=大小)...

祝你好运!

关于c++ - 套接字上的FTP写入错误的文件和不同大小的C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61378526/

相关文章:

c# - X-SERVERSOCKET : REUSE Fiddler

sockets - conn (net.Conn) 并不总是写在套接字上

c++ - 罗技 G29 操纵杆中的力反馈

c++ - 将临时对象的 c_str 返回值传递给 printf

sockets - 套接字编程中select()中的“nfds”参数

javascript - 字符串在 Node 中的 TLS 套接字连接中的另一端连接

iPhone TCP 连接

c - 如果内核支持 IPv6,如何从用户空间进行测试?

c++ - Qt 4.8 信号/插槽在 moveToThread() 之后未调用

c++ - 从 Fortran 返回字符串到 C++