1

在一个函数中,得到 unsigned char && unsigned char 长度,

void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet) 
{
    std::vector<unsigned char> vec(packet, packet+pkthdr->len); // optimized from foo.
    std::stringstream scp;
    for (int i=0;i<pkthdr->len;i++) {
        scp<<vec[i];
    }
    std::string mystr =  std::string(scp.rdbuf()->str());
    std::cout << "WAS: " << packet << std::endl;
    std::cout << "GOOD: " << scp.str() << std::endl;
    std::cout << "BAD: "  << scp.str().c_str() << std::endl;
    std::cout << "TEST: " << mystr.size() << std::endl;
    assert(mystr.size() == pkthdr->len); 
}

结果:

  • WAS:什么都不打印(猜想有一个指向 const .. case 的指针)
  • 好:打印数据
  • BAD:什么都不打印
  • 测试,断言:打印 mystr.size() 等于传递的无符号字符大小。

我试过:

  • string.assign(scp.rdbuf());
  • memcpy(char, scp.str(), 10);
  • 创建/分配临时字符、字符串的不同方法

没有帮助..它想要获得一个包含数据的std::cout 'able std::string (从foo中挑选,它是unsigned char,它是数据包数据)。

猜测原始foo可能不是以空值终止的,或者问题是这样的 - 简单,但无法进入......这里要寻找什么?

(此代码是使用 libpcap 的另一种尝试,只是以 C++ 方式打印数据包,而不使用已知的 C++ 魔术包装器,如 libpcapp)。

4

3 回答 3

3

为了进行快速测试,请检查scp.str().size() == strlen(scp.str().c_str())字符串中是否嵌入了 '\0' 字符,这就是我怀疑正在发生的情况。

于 2010-12-02T20:13:16.443 回答
2

我认为你的做法是错误的。看起来您在这里处理的是二进制数据,在这种情况下,您不能期望将其作为文本有意义地输出到屏幕上。你真正需要的是一个十六进制转储

const unsigned char* ucopy = packet;
std::ios_base::fmtflags old_flags = std::cout.flags();
std::cout.setf(std::ios::hex, std::ios::basefield);

for (const unsigned char* p = ucopy, *e = p + pkthdr->len; p != e; ++p) {
    std::cout << std::setw(2) << std::setfill('0') << static_cast<unsigned>(*p) << " ";
}

std::cout.flags(old_flags);

这将逐字节输出数据,并让您检查二进制数据的各个十六进制值。空字节将简单地输出为00.

于 2010-12-02T20:16:56.863 回答
1

std::cout.good()在失败的输出尝试后检查。我的猜测是输出有一些失败(即试图将不可打印的字符写入控制台),它设置failbitcout.

还要检查以确保字符串不以 a 开头NULL,这会导致空输出成为预期的行为:)

(旁注,如果您使用 C++ ,请使用reinterpret_castfor ;))unsigned char *ucopy = (unsigned char*)packet;

于 2010-12-02T20:04:18.800 回答