pommmm 2021-09-06 17:44 采纳率: 50%
浏览 48
已采纳

TCP协议socket在子线程向缓冲区写数据出现 段错误 (核心已转储) 问题

在主线程实例化了一个 client 客户端,然后把它传到子线程里面去使用。

在子线程类的 callback 回调函数里面想用 writeData() 函数向缓冲区写入数据,运行到 callback()函数的client2->writeData() 时显示 段错误 (核心已转储)。但是如果我在构造函数里面调用 writeData() 函数就没问题可以正常运行,请问是什么原因引起的呢?

 

子线程类代码:

#ifndef ANSWERTHREAD_H
#define ANSWERTHREAD_H
#include <QThread>
#include <QDebug>
#include "tcpclient.h"
#include "ros/ros.h"
#include "communication/Answer.h"


class AnswerThread : public QThread
{
public:
    AnswerThread(ros::NodeHandle&,TCPClient);
    void registersub();
    void callback(const communication::Answer::ConstPtr&);
    void run();
    ~AnswerThread();

protected:
    ros::NodeHandle nh;
    ros::Subscriber sub;
    TCPClient *client2;
};

AnswerThread::AnswerThread(ros::NodeHandle& _nh,TCPClient _client)
{
	nh = _nh;
	client2 = &_client;
	client2 -> connectServer();
	qDebug()<<"新建了一个答案线程!";  //测试用
}


void AnswerThread::callback(const communication::Answer::ConstPtr& msg)
{
	ROS_INFO("接收了一条消息,答案类型为%c", msg->answer_type);   //测试用
	char *data;
    data = new char[3];
    data[0] = '\x02'; data[1] = '\x32'; data[2] = '\x03';
    client2->writeData(data,3);
}

void AnswerThread::registersub()
{
	sub = nh.subscribe("chatter2", 10, &AnswerThread::callback,this);  
	ros::spin();
    	
};

void AnswerThread::run()
{
	std::cout<<"答案发送线程启动"<<std::endl; 
//-----------------------------从rostopic中接收答案数据--------------------------------------
	//sub = nh.subscribe("chatter2", 10, &callback,this);  
	registersub();


	QThread::exec();
	//qDebug()<<"任务完成,退出答案线程";
}

AnswerThread::~AnswerThread()
{
	client2 -> closeConnect();
}
    

#endif // ANSWERTHREAD_H

客户端类代码:

#include "tcpclient.h"

TCPClient::TCPClient(QHostAddress address,int port)  //定义构造函数
{
    Address = address;
    Port = port;
}

TCPClient::~TCPClient()     //定义析构函数
{
    delete m_tcpsocket;
}

void TCPClient::writeData(char *data,int size)
{
    m_tcpsocket->write(data,size);  //第一个参数是写入的数据,第二个参数是最大写入字节数
    m_tcpsocket->waitForBytesWritten(); //这个函数是等待数据发送完毕再返回
}

void TCPClient::connectServer()  //连接服务器函数
{
    m_tcpsocket = new QTcpSocket;
    m_tcpsocket->connectToHost(Address,Port);
    if(!m_tcpsocket->waitForConnected(5000000)) //等待5000s如果还没连接上,报错 
        std::cout<<"TCP socket connect to server failed! Server Port:"<<Port<<std::endl;
    //else std::cout<<"TCP socket connect to server succeed! Server Port:"<<Port<<std::endl;
}

void TCPClient::closeConnect()  //关闭连接函数
{
    m_tcpsocket->disconnectFromHost();
   if (m_tcpsocket->state() == QAbstractSocket::UnconnectedState || m_tcpsocket->waitForDisconnected()) delete m_tcpsocket;
}
  • 写回答

2条回答 默认 最新

  • qfl_sdu 2021-09-06 17:51
    关注

    AnswerThread::AnswerThread(ros::NodeHandle& _nh,TCPClient _client)这里,第二个参数的_client,你如果是一个临时变量,出了作用域它就被释放了,用new创建一个TcpClent传进来。new 出来的tcpclient最好用成员变量或者全局变量保存一下,避免系统给释放了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已采纳回答 9月6日
  • 创建了问题 9月6日

悬赏问题

  • ¥15 用三极管设计—个共射极放大电路
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示