我正在用C ++创建一个FTP客户端。
使用我的ftp客户端下载更大的文件后。我看到随机字符会被添加到文件中。
在图片中,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();
}
}
}
答案 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(...)
)。