ftp客户端 - 在get之后插入随机字符

时间:2016-03-12 06:59:52

标签: c++ ftp

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

使用我的ftp客户端下载更大的文件后。我看到随机字符会被添加到文件中。

enter image description here

在图片中,protocol变为pr¿_ÿotocol,它们也会插入同一文件中的许多其他位置。

我注意到了:

  • 当我更改缓冲区大小时,这些字符会有所不同,有时会\377或反斜杠后跟3位

  • 当缓冲区大小减少时,它们会变得更频繁

我确保使用图像模式。可能导致这种情况的原因是什么?

我在TCPSocket中的阅读代码:

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

        bytesRead = ::read(sd, buf, BUFF_SIZE);
        if (bytesRead == 0) {
            break;
        }
        if (bytesRead > 0) {
            result << buf;
        }
    } while (poll(&ufds, 1, 1000) > 0);
    return result;
}

我在Main.cpp中获取代码

 else if (command == command::GET) {
        string filename;
        cin >> filename;
        string dataHost;
        int dataPort;
        if (enterPasiveMode(dataHost, dataPort)) {
            dataSocket = new TCPSocket(dataHost.c_str(), dataPort);
            if (fork() == 0) {
                stringstream result = dataSocket->long_read();

                ofstream ofs;

                ofs.open(filename);
                if (ofs.is_open()) {
                    copy(istreambuf_iterator<char>(result), istreambuf_iterator<char>(), ostreambuf_iterator<char>(ofs));

                    ofs.close();
                }
                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().str();
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

来自你的`long_read'功能:

char buf[BUFF_SIZE];
...
    bytesRead = ::read(sd, buf, BUFF_SIZE);
    ...
        result << buf;

buf是char[],这意味着当用作字符串时,数据应以\0结尾。这本身就意味着<<无需将bytesRead添加到result,而是添加到第一个\0。根据数据,这可以在bytesRead之前或甚至之后,在这种情况下,您从单位化buf获取数据,直到找到一些\0。此\0甚至可以在buf之外。

或者简而言之:不要混合字符串语义(char[]<<,...)和八位字节语义(::read(...))。