最近,我正在研究 car-to-X 通信并使用两个车载单元 (OBU)。可以使用 gpsd、gpsd 客户端读取和监视两个模块上的 GPS 数据,并且我还可以使用 iPerf 测量网络性能。为此,一台设备充当服务器,另一台充当客户端。现在,我想将这两个设备与两台不同的笔记本电脑连接起来,测量网络性能以及读取 OBU 之外的 GPS 数据。此外,我需要在 GPS 数据和 iPerf 输出之间进行同步,以便我可以检测 TPV(时间、位置、速度)明智的吞吐量、延迟等。现在我需要将 GPS 和 iPerf 数据同步在一起,以便我可以将它们存储为日志-文件并稍后处理数据。有没有人可以帮助我知道如何做到这一点。我已经尝试过一种解决方案 - GPS 和 iperf 数据的时间戳,并存储到日志中。我有第二个解决方案,即使用 -f 选项将 GPS 数据作为 iperf 有效负载发送。我想尝试第二个,但不确定该怎么做。真正感谢任何人的帮助。
问问题
458 次
1 回答
0
您没有提及您熟悉的脚本语言或编程语言。有很多方法可以做到这一点,从简单的 python 或 bash 脚本到更复杂的 C++ 程序。
我不想为你写一个完整的演示软件,因为你不知道你在寻找什么,但我能够获取这个示例 c++ gpsd 客户端的一部分并对其进行修改,以便它也运行 iperf 并输出为 csv(你然后可以通过管道传输到记录器,或者您想要这样做)。
#include <iostream>
#include <iomanip>
#include <ctime>
#include <sstream>
#include <memory>
#include <libgpsmm.h>
std::string exec(const char *cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != NULL) result += buffer.data();
}
return result;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Please execute command with a remote iperf server. Exiting." <<
"\n";
return 1;
}
gpsmm gps_rec("localhost", DEFAULT_GPSD_PORT);
if (gps_rec.stream(WATCH_ENABLE | WATCH_JSON) == NULL) {
std::cerr << "No GPSD running.\n";
return 1;
}
for (;;) {
// run iperf and get output in a string (note: needs error checking!)
// the cut portion is there to remove the first column from the csv output
// which is time, as we'll take the gps time instead.
std::stringstream iperfCmd;
iperfCmd << "iperf -c " << argv[1] << " -ey C | cut -d , -f 2-9";
const std::string& tmp = iperfCmd.str();
const char *iperfCmdArr = tmp.c_str();
std::string iperfOutput = exec(iperfCmdArr);
struct gps_data_t *newdata;
if (!gps_rec.waiting(50000000)) continue;
if ((newdata = gps_rec.read()) == NULL) {
std::cerr << "Read error.\n";
return 1;
} else {
while (((newdata = gps_rec.read()) == NULL) ||
(newdata->fix.mode < 1)) {
// Do nothing; don't want to output wrong initial time
}
timestamp_t ts = newdata->fix.time;
double latitude = newdata->fix.latitude;
double longitude = newdata->fix.longitude;
// convert GPSD's timestamp_t into time_t
time_t seconds;
seconds = (time_t)ts;
auto tm = *std::localtime(&seconds);
std::ostringstream oss;
oss << std::put_time(&tm, "%d-%m-%Y %H:%M:%S");
auto time_str = oss.str();
// set decimal precision
std::cout.precision(6);
std::cout.setf(std::ios::fixed, std::ios::floatfield);
std::cout << time_str << "," <<
latitude << "," <<
longitude << "," << iperfOutput;
// uncomment below to break out of for loop (will only output 1 iteration)
// return 0;
}
}
return 0;
}
您可以修改 iperfCmd 变量以更改 iperf 命令。例如,如果要运行双向测试,可以将其更改为“-rey C”。查看 iperf --help 以了解您的需要,但您必须保留 CSV 输出的“-y C”标志。如果你有 gpsd(有时还有必要的 libgps-dev 库),你可以这样编译代码:
g++ -Wall -std=c++14 -pedantic $(pkg-config --cflags --libs libgps) gpsd-iperf-example.cpp -o gpsd-iperf-example
然后运行(按 CTRL-C 停止):
gpsd-iperf-example servername
假设 gpsd 工作正常,并且您使用的是 iperf v2,输出应如下所示:
07-05-2017 19:05:10,45.3XXXXX,-75.8XXXXX,192.168.2.36,40466,192.168.2.28,5001,4,0.0-10.0,286785536,228615722
07-05-2017 19:05:11,45.3XXXXX,-75.8XXXXX,192.168.2.36,40468,192.168.2.28,5001,4,0.0-10.0,328859648,261792317
07-05-2017 19:05:12,45.3XXXXX,-75.8XXXXX,192.168.2.36,40470,192.168.2.28,5001,4,0.0-10.0,293601280,234307789
您可以进一步解析或简单地调整 c++ 程序。不确定这是否是您正在寻找的东西,但同样,有很多方法可以做到这一点,只需四处寻找代码片段并根据您的需要进行调整。
于 2017-05-07T23:08:23.000 回答