QT套接字与Linux套接字通信实现

5星 · 超过95%的资源 需积分: 44 61 下载量 149 浏览量 更新于2024-09-15 1 收藏 3KB TXT 举报
"QT库中的socket通信与Linux系统socket接口的交互" 在QT框架中,开发者可以使用QT的网络模块来实现socket通信。QT的QTcpSocket类是用于TCP(传输控制协议)通信的主要工具,它封装了底层的socket API,提供了一套面向对象的接口,简化了网络编程。在描述的示例中,我们看到一个名为`Client`的类,该类继承自QObject,并且使用QTcpSocket来实现客户端的socket通信。 首先,`Client`类包含了必要的信号和槽来处理socket的各种状态变化。例如,`connected()`信号表示socket已经成功连接到服务器,`error(QAbstractSocket::SocketError)`信号则会在发生错误时触发,而`readyRead()`信号表明socket可以读取数据,因为服务器已发送了新的数据。 在`Client`类的构造函数中,我们看到了对这些信号和槽的连接。当socket连接成功时,会调用`startTransfer()`槽函数;当出现错误时,调用`connectError(QAbstractSocket::SocketError)`槽函数;而当socket准备好读取数据时,调用`startRead()`槽函数。 `Client`类的`start()`方法接收服务器的地址和端口号,然后使用`QHostAddress`来解析地址,并通过`client.connectToHost(addr, port)`发起连接请求。在析构函数中,`client.close()`确保在对象销毁时,socket连接会被关闭,以释放资源。 在实际的socket通信中,Linux系统提供的socket API是低级别的接口,它通常涉及系统调用如`socket()`, `bind()`, `listen()`, `accept()`, `connect()`, `read()`, `write()`等。QT的QTcpSocket类通过这些系统调用来实现其功能,但提供了更高级别的抽象,使得程序员不需要直接处理这些底层细节。 在Linux中,socket通信通常涉及以下步骤: 1. 创建socket:通过`socket()`系统调用创建一个socket描述符。 2. 绑定地址:使用`bind()`将socket与本地IP地址和端口关联。 3. 对于服务器,监听连接:通过`listen()`设置socket为监听模式。 4. 对于客户端,连接服务器:使用`connect()`尝试连接到服务器的IP和端口。 5. 数据传输:使用`send()`或`write()`发送数据,用`recv()`或`read()`接收数据。 6. 关闭连接:通过`close()`系统调用关闭socket。 QT的QTcpSocket类将这些步骤封装起来,使得在QT应用中进行socket通信更加便捷,同时也提供了异常处理和异步操作的能力。因此,使用QT的socket通信比直接调用Linux的socket API更加直观和易于管理。
2020-07-23 上传
Linux下面QT写Can通信程序,网络上有很多例子都是互相抄的;本人因为项目原因,通过源代码Socket函数,写了完整的程序,含有2个案例;分享给大家; 这里主要是包含几个步骤,1:绑定Socket;2:cna/can1的设置,3:波特率的设置(如果发送和接收波特率不一致肯定不行的);4:发送;5:接收处理; 下面就贴出部分代码: void MyWindow::startcan(int number) { int ret = 0; //can先关闭 设置好波特率后 再开启can if(number == 0) //can0 { system("ifconfig can0 down");//先关闭 system("ip link set can0 up type can bitrate 50000 triple-sampling on");//设置波特率 system("ifconfig can0 up");//再开启 } else //can1 { system("ifconfig can1 down");//先关闭 system("ip link set can1 up type can bitrate 50000 triple-sampling on");//设置波特率 system("ifconfig can1 up");//再开启 } socket = ::socket(PF_CAN,SOCK_RAW,CAN_RAW); struct ifreq ifr; strcpy((char *)(ifr.ifr_name),number == 0 ? "can0" : "can1"); ioctl(socket,SIOCGIFINDEX,&ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; ret = bind(socket,(struct sockaddr*)&addr,sizeof(addr)); if (ret OpenCan(50000); ArmCan = new Thread(zyhapi,socket,port); ArmCan->start(); } void MyWindow::stopcan(int number) { if(ArmCan) { ArmCan->stop(); ArmCan->terminate(); ArmCan->wait(); } zyhapi->CloseCan(number); } //发送 void MyWindow::on_sendbtn_clicked() { /* struct can_frame frame; memset(&frame,0,sizeof(struct can_frame)); std::string str=ui->edit->text().toStdString(); if(str.length() > 8) { QMessageBox::about(this,"error","length of send string must less than 8 bytes"); return; } */ struct can_frame frame; memset(&frame,0,sizeof(struct can_frame)); char buf[8]={0X20,0XFF,0X01,0X02,0X03,0X04,0XFF,0XFF}; frame.can_id = 0x00000020;//发出去的帧ID即:0X00000020 frame.can_dlc = 8;//帧数据长度 for(int i=0;i<frame.can_dlc;i++) { frame.data[i]=buf[i];//帧数据 } //frame.can_id = 0x123; //strcpy((char*)frame.data,str.c_str()); //frame.can_dlc = str.length(); sendto(socket,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr)); /* struct can_frame frame; char buf[8]={0X20,0XFF,0X01,0X02,0X03,0X04,0XFF,0XFF}; frame.can_id = 0x00000020;//发出去的帧ID即:0X00000020 frame.can_dlc = 8;//帧数据长度 for(int i=0;iWriteCan(frame.can_id,frame.data,frame.can_dlc);//发数据,通过can端口-- 暂时默认 CAN0 端口 */ }