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

时间:2016-03-12 17:45:03

标签: c++ ftp

我正在创建一个FTP客户端。

我从服务器获取了一个gif,但之后gif已损坏。

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

filemerge

怎么会这样?我确保使用图像模式。

这是我在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();
            }
        }
    }

修改

我确实使用二进制模式。当我传输一个文本文件(虽然尺寸较小)时,它没有这个问题。这是输出:

binarymode

编辑2

Wireshark的输出显示Request: TYPE IResponse: Opening BINARY mode

wireshark

1 个答案:

答案 0 :(得分:0)

默认情况下,FTP服务器和客户端以&#34; ASCII模式&#34;执行数据传输,这意味着任何CRLF序列都会即时转换到主机的ASCII行结尾(例如在Unix mmachines上只是裸LF)。此行为由RFC 959强制执行;见3.1.1.1节。

要将数据作为二进制文件传输,并避免ASCII模式转换,您的FTP客户端将首先发送TYPE命令,例如:< / p>

TYPE I

然后应该按原样传输.gif文件,不对任何CRLF序列进行替换/转换。

希望这有帮助!