我在后端写了一个函数通过popen调用tshark命令行不断抓取流量,想通过websocket将抓取到的数据包信息发送到前端,并且显示数据包的信息,目前已经实现了向前端发送信息,但是执行后一直在抓取数据包,想在前端设置比如一个按钮来停止后端tshark抓包的命令,停止抓包要求不能将整个web应用停止,尝试了许多办法没有得到解决,有没有什么好的办法。下面是我后端websocket控制器的代码:
void catchtraffic::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr, std::string &&message, const WebSocketMessageType &type)
{
char outBuffer[1024]; // 保存运行后输出的结果
std::string s2;
s2="exec tshark -i eth0 -w pcaps.pcap -l -P";//将采集流量保存
char c[100];
strcpy(c,s2.c_str());
char *cmdStr = c; // 准备运行的命令
FILE * pipeLine = popen(cmdStr,"r"); // 建立流管道
if(!pipeLine){ // 检测流管道
exit(0);
perror("Fail to popen\n");
}
while(fgets(outBuffer, 1024, pipeLine) != NULL){ // 获取输出
vector<string> res;
string result;//临时存放输出信息
stringstream input;
input << outBuffer;//输出信息的字符串读入到input中
while (input >> result)
res.push_back(result);//将以空格为分隔的字符串存入res中
Json::Value traffic;
traffic["number"]=res[0];
traffic["time"]=res[1];
traffic["sip"]=res[2];
traffic["dip"]=res[4];
traffic["protocol"]=res[5];
traffic["length"]=res[6];
Json::FastWriter fastWriter;
std::string output = fastWriter.write(traffic);
wsConnPtr->send(output);
}
cout<<"结尾"<<endl;
pclose(pipeLine);
}
最简单的办法不是你后端一直循环,而是你前端放个timer,每提交一次后端就返回一组信息,前端不再提交了那么后端自然也就不再返回信息了
写个死循环是最不可取的,你这耦合度太高了
函数可以设置一个抓取次数作为参数传递过来,当次数到达要求的时候,return 掉函数,当需要的时候前端在请求一次即可。