C++ FTP客户端--gif中的CR字符在获取后被删除

C++ FTP客户端--gif中的CR字符在获取后被删除,c++,ftp,C++,Ftp,我正在创建一个FTP客户端 我正在从服务器获取gif,但在这之后gif已损坏 当我更改文件扩展名以查看差异时,我看到 CR/LF字符消失 这怎么可能?我确保使用图像模式 这是我在TCP套接字中读取的代码 string TCPSocket::long_read() { pollfd ufds; ufds.fd = sd; ufds.events = POLLIN; ufds.revents = 0; ssize_t bytesRead = 0; s

我正在创建一个FTP客户端

我正在从服务器获取gif,但在这之后gif已损坏

当我更改文件扩展名以查看差异时,我看到 CR/LF字符消失

这怎么可能?我确保使用图像模式

这是我在TCP套接字中读取的代码

string TCPSocket::long_read()
{
    pollfd ufds;
    ufds.fd = sd;
    ufds.events = POLLIN;
    ufds.revents = 0;
    ssize_t bytesRead = 0;
    string result;
    char* buf = new char[LONGBUFLEN];
    do {
        bzero(buf, LONGBUFLEN);

        bytesRead = ::read(sd, buf, LONGBUFLEN);
        if (bytesRead == 0) {
            break;
        }
        if (bytesRead > 0) {
            result = result + string(buf, bytesRead);
        }
    } while (poll(&ufds, 1, 1000) > 0);
    return result;
}
这里是我在main.cpp中获取的代码

    else if (command == command::GET) {
        string filename;
        cin >> filename;
        string dataHost;
        int dataPort;
        if (enterPassiveMode(dataHost, dataPort)) {
            dataSocket = new TCPSocket(dataHost.c_str(), dataPort);
            if (fork() == 0) {
                string result = dataSocket->long_read();
                size_t length = result.size();
                char* resultArr = new char[length];
                memcpy(resultArr, result.data(), length);

                //                    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
                FILE* file = fopen(filename.c_str(), "w+b");
                if (file) {
                    fwrite(resultArr, length, 1, file);
                    fclose(file);
                }
                else {
                    cout << "open failed";
                }
                break;
            }
            else {
                writeAndImmediateRead(rfc959::TYPE_I);
                controlSocket->write(rfc959::RETRIVE(filename));
                string result = controlSocket->read();
                cout << result;
                int reply = Parser::firstDigit(result);

                // I'll remove incomplete local file if request fails
                if (reply != rfc959::POSITIVE_PRELIMINARY_REPLY) {
                    remove(filename.c_str());
                    continue;
                }

                wait(NULL);
                cout << controlSocket->long_read();
            }
        }
    }
else if(command==command::GET){
字符串文件名;
cin>>文件名;
字符串数据主机;
int数据端口;
if(enterPassiveMode(数据主机、数据端口)){
dataSocket=newtcpsocket(dataHost.c_str(),dataPort);
如果(fork()==0){
字符串结果=dataSocket->long_read();
size_t length=result.size();
char*resultArr=新字符[长度];
memcpy(resultar,result.data(),length);
//模式=S|u IRUSR | S|u IWUSR | S|u IRGRP | S|IROTH;
FILE*FILE=fopen(filename.c_str(),“w+b”);
如果(文件){
fwrite(resultar,length,1,file);
fclose(文件);
}
否则{
无法写入(rfc959::检索(文件名));
字符串结果=controlSocket->read();

cout默认情况下,FTP服务器和客户端以“ASCII模式”执行数据传输,这意味着任何CRLF序列都会被动态转换为主机的ASCII行结尾(例如,在Unix MMachine上仅为裸LF)。此行为由强制执行;请参阅第3.1.1.1节

要以二进制形式传输数据并避免ASCII模式转换,您的FTP客户端需要首先发送
TYPE
命令,例如:

然后,您的
.gif
文件应按原样传输,在任何CRLF序列上不进行替换/转换


希望这有帮助!

您需要设置二进制模式,而不是默认的ASCII模式。@tomtom:请验证您是否真的将
类型I
发送到应用程序中的服务器,并且您得到了成功的响应。因为它是从命令行工作的,所以我认为您设置的类型是错误的。但我的假设是:可以根据您显示的内容进行验证。因此,您的gif文件在服务器端大965744字节,而在客户端小?是按照标题中的说明删除了CRLF还是仅删除了CR?您是否计算了总共收到的字节数,并将其与您在磁盘上写入的文件中的字节数进行了比较?回答所有这些问题您可以检测出哪一步出错的问题。
result.size()
是否显示了预期的大小,并且只有写入的文件较小,或者
result.size()
已经出错?您是否计算了收到的字节数(即字节读取的总和),以检查CR在传输过程中是否丢失(错误的图像模式)或者在附加到结果时?我确实确保使用二进制模式。编辑问题以显示输出
TYPE I