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

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日

悬赏问题

  • ¥20 有没有会写mysql的,有偿做个问题
  • ¥20 win11账户锁定时间设为0无法登录
  • ¥45 C#学生成绩管理系统
  • ¥15 VB.NET2022如何生成发布成exe文件
  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?