QT使用QSocketNotifier监听socket事件

QSocketNotifier简介

QSocketNotifier监听系统文件操作,将操作转换为Qt事件进入系统的消息循环队列,通过connect槽函数处理事件。
1、QSocketNotifier可以监听C/C++写的socket,通常C/C++的socket会写一个线程轮询接收数据,如果socket收发数据不频繁,那么这个socket大部分时间都是在空跑的,比较浪费cpu资源;可以使用QSocketNotifier监听socket,当有数据接收时触发槽函数,不再使用线程轮询,类似与QTcpSocket使用信号槽异步接收数据。
2、QSocketNotifier还可以监听其他特殊socket,比如linux系统的Netlink套接字;Netlink是实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口,当有网卡、串口设备、USB设备等插拔时都会触发Netlink套接字。
3、QSocketNotifier也可以监听linux下的消息队列mqueue,消息队列是建立在socket基础上的。
本章分别对前两种场景举例。

QSocketNotifier监听tcpsocket接收数据

使用C/C++的socket函数写一个tcp客户端,QSocketNotifier监听socket返回的文件描述符,槽函数接收数据,支持windows和linux跨平台。
tcpclient.h

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QObject>
#include <stdint.h>
#include <pthread.h>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#define socklen_t int
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <QNetworkInterface>
#include <QSocketNotifier>
#include <QBuffer>

typedef struct {
    int32_t fd;
    int32_t localPort;
    int32_t remotePort;
    int32_t isStart;
    int32_t isLoop;
    int32_t notRemoteInit;
    pthread_t threadId;
    int isServer;//0客户端,1服务端

    //char serverIp[30];
    void* user;
    struct sockaddr_in local_addr;
    struct sockaddr_in remote_addr;
    void (*receive)(char *data, int32_t nb_data,void* user);
}TcpHandle;

class tcpClient : public QObject
{
    Q_OBJECT
public:
    explicit tcpClient(QObject *parent = nullptr);

    int32_t create_tcpClient(char* serverIp, int32_t serverPort, int32_t plocalPort);
    void stop_tcpClient();
    int32_t sendData_tcpClient(char* data, int32_t len);
signals:
private:
    QSocketNotifier *socket_notifier;
    int netlink_socket;

    TcpHandle *pTcpHandle;
public slots:
    void slot_parseDeviceInfo();
};

#endif // TCPCLIENT_H

tcpclient.cpp

#include "tcpclient.h"

tcpClient::tcpClient(QObject *parent) : QObject(parent)
{
    pTcpHandle = (TcpHandle *)malloc(sizeof(TcpHandle));
    pTcpHandle->fd = -1;
}

int32_t tcpClient::create_tcpClient(char *serverIp, int32_t serverPort, int32_t plocalPort)
{
    if (pTcpHandle == NULL)		return -1;
    pTcpHandle->isServer = 0;

    pTcpHandle->localPort = plocalPort;
    pTcpHandle->fd = -1;
    pTcpHandle->remotePort = serverPort;

#ifdef _WIN32
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2, 2);
    WSAStartup(wVersionRequested, &wsaData);//初始化socket库
#endif

    pTcpHandle->local_addr.sin_family = AF_INET;
    pTcpHandle->local_addr.sin_port = htons(pTcpHandle->localPort);
    // lcl_addr.sin_addr.s_addr=inet_addr(ip);
    pTcpHandle->local_addr.sin_addr.s_addr = INADDR_ANY;
    if((pTcpHandle->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)//客户端只需要一个套接字文件描述符,用于和服务器通信
    {
        perror("socket");
        return -2;
    }

    pTcpHandle->remote_addr.sin_family = AF_INET;
    pTcpHandle->remote_addr.sin_port = htons(pTcpHandle->remotePort);
    pTcpHandle->notRemoteInit=serverPort>0?0:1;

#ifdef _WIN32
    pTcpHandle->remote_addr.sin_addr.S_un.S_addr=inet_addr(serverIp);
#else
    pTcpHandle->remote_addr.sin_addr.s_addr = inet_addr(serverIp);//将点分十进制IP转换成网络字节序IP
#endif

    if(::connect(pTcpHandle->fd, (struct sockaddr *)&pTcpHandle->remote_addr, sizeof(pTcpHandle->remote_addr)) < 0)
    {
        perror("connect");
        return -3;
    }

    //监听socket文件描述符
    socket_notifier = new QSocketNotifier(pTcpHandle->fd, QSocketNotifier::Read, this);
    connect(socket_notifier, SIGNAL(activated(int)), SLOT(slot_parseDeviceInfo())); //will always active

    return 0;
}

void tcpClient::slot_parseDeviceInfo()
{
    char buffer[2048] = { 0 };

    memset(buffer, 0, 2048);
    recv(pTcpHandle->fd, buffer, 2048, 0);
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<buffer;
}

void tcpClient::stop_tcpClient()
{
    if(socket_notifier) socket_notifier->setEnabled(false);
    if (pTcpHandle == NULL)
        return;
    if (pTcpHandle->fd > 0)
    {
#ifdef _WIN32
        closesocket(pTcpHandle->fd);
#else
        close(pTcpHandle->fd);
#endif
        pTcpHandle->fd = -1;
    }
}

int32_t tcpClient::sendData_tcpClient(char *data, int32_t len)
{
    if (pTcpHandle == NULL || !pTcpHandle->isStart || pTcpHandle->notRemoteInit || data==NULL)	return -1;
    return sendto(pTcpHandle->fd, data, len, 0, (struct sockaddr*) &pTcpHandle->remote_addr,sizeof(struct sockaddr));
}

QT调用示例

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ptcpClient = new tcpClient(this);
    ptcpClient->create_tcpClient("192.168.3.32",9090,0);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    ptcpClient->sendData_tcpClient(ui->lineEdit->text().toLatin1().data(),ui->lineEdit->text().size());
}

void MainWindow::on_pushButton_2_clicked()
{
    ptcpClient->stop_tcpClient();
}

QSocketNotifier监听netlink套接字

devmonitor.h

#ifndef DEVMONITOR_H
#define DEVMONITOR_H

#include <QObject>
#include <QDebug>
#include <QNetworkInterface>
#include <QSocketNotifier>

class devMonitor : public QObject
{
    Q_OBJECT
public:
    explicit devMonitor(QObject *parent = nullptr);
    ~devMonitor();

    bool startSocket();
    bool stopSocket();
private:
    bool initSocket();
    void parseLine(const QByteArray& line);
    QSocketNotifier *socket_notifier;
    int netlink_socket;
public slots:
    void slot_parseDeviceInfo();
};

#endif // DEVMONITOR_H

devmonitor.cpp

#include "devmonitor.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
#else

#endif

#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <errno.h>
#include <unistd.h>

#include <QSocketNotifier>
#include <QBuffer>

#define UEVENT_BUFFER_SIZE      2048
enum udev_monitor_netlink_group {
    UDEV_MONITOR_NONE,
    UDEV_MONITOR_KERNEL,
    UDEV_MONITOR_UDEV
};
devMonitor::devMonitor(QObject *parent) : QObject(parent)
{

}

devMonitor::~devMonitor()
{
    stopSocket();
    close(netlink_socket);
    netlink_socket = -1;
}

bool devMonitor::startSocket()
{
    if (!initSocket())
        return false;
    socket_notifier->setEnabled(true);
    return true;
}

bool devMonitor::stopSocket()
{
    if (netlink_socket!=-1) {
        socket_notifier->setEnabled(false);
        close(netlink_socket);
        netlink_socket = -1;
    }
    return true;
}

bool devMonitor::initSocket()
{
    struct sockaddr_nl snl;
    const int buffersize = 16 * 1024 * 1024;
    int retval;

    memset(&snl, 0x00, sizeof(struct sockaddr_nl));
    snl.nl_family = AF_NETLINK;
    snl.nl_groups = UDEV_MONITOR_KERNEL;

    netlink_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

    if (netlink_socket == -1) {
        qWarning("error getting socket: %s", strerror(errno));
        return false;
    }

    /* set receive buffersize */
    setsockopt(netlink_socket, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize));
    retval = bind(netlink_socket, (struct sockaddr*) &snl, sizeof(struct sockaddr_nl));
    if (retval < 0) {
        qWarning("bind failed: %s", strerror(errno));
        close(netlink_socket);
        netlink_socket = -1;
        return false;
    } else if (retval == 0) {
        //from libudev-monitor.c
        struct sockaddr_nl _snl;
        socklen_t _addrlen;

        /*
         * get the address the kernel has assigned us
         * it is usually, but not necessarily the pid
         */
        _addrlen = sizeof(struct sockaddr_nl);
        retval = getsockname(netlink_socket, (struct sockaddr *)&_snl, &_addrlen);
        if (retval == 0)
            snl.nl_pid = _snl.nl_pid;
    }

    socket_notifier = new QSocketNotifier(netlink_socket, QSocketNotifier::Read, this);
    connect(socket_notifier, SIGNAL(activated(int)), SLOT(slot_parseDeviceInfo())); //will always active
    socket_notifier->setEnabled(false);
    return true;
}

void devMonitor::slot_parseDeviceInfo()
{
    QBuffer buffer;
    QByteArray data;
    data.resize(UEVENT_BUFFER_SIZE*2);
    data.fill(0);
    size_t len = read(socket_notifier->socket(), data.data(), UEVENT_BUFFER_SIZE*3);
//    qDebug("read fro socket %d bytes", len);
    data.resize(len);
    data = data.replace(0, '\n').trimmed(); //In the original line each information is seperated by 0
    if (buffer.isOpen())
        buffer.close();
    buffer.setBuffer(&data);
    buffer.open(QIODevice::ReadOnly);
    while(!buffer.atEnd()) { //buffer.canReadLine() always false?
        QByteArray line = buffer.readLine().trimmed();
        qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<line;
//        parseLine(buffer.readLine().trimmed());
    }
    buffer.close();
}

调用示例

    devMonitor * watcher = new devMonitor;
    watcher->startSocket();

QSocketNotifier监听netlink,USB热插拔测试

插入USB摄像头:


11:06:53: Starting /home/chuwei/chw/testCode/testQSocketNotifier/build-testQSocketNotifier-Desktop_Qt_5_14_2_GCC_64bit-Debug/testQSocketNotifier ...
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=189"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=6"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=bus/usb/001/007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_device"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "BUSNUM=001"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNUM=007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11708"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/1/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc01ip00in00"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11709"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=video4linux"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=81"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11710"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=video4linux"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=81"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11711"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=media"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=236"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11712"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=input"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=3/bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "NAME=\"Integrated_Webcam_HD: Integrate\""
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PHYS=\"usb-0000:02:03.0-1/button\""
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PROP=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "EV=3"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "KEY=100000 0 0 0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=input:b0003v0BDAp5763e6728-e0,1,kD4,ramlsfw"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11713"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=input"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=13"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=69"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=input/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11714"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "bind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=bind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DRIVER=uvcvideo"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/1/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc01ip00in00"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11715"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "add@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=add"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DRIVER=uvcvideo"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/2/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc02ip00in01"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11716"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "bind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=bind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DRIVER=uvcvideo"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/2/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc02ip00in01"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11717"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "bind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=bind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=189"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=6"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=bus/usb/001/007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_device"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DRIVER=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "BUSNUM=001"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNUM=007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11718"

拔掉USB摄像头

[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=video4linux"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=81"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=video0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11719"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/video4linux/video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=video4linux"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=81"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=video1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11720"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=input"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=13"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=69"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=input/event5"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11721"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/input/input11"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=input"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=3/bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "NAME=\"Integrated_Webcam_HD: Integrate\""
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PHYS=\"usb-0000:02:03.0-1/button\""
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PROP=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "EV=3"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "KEY=100000 0 0 0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=input:b0003v0BDAp5763e6728-e0,1,kD4,ramlsfw"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11722"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=media"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=236"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=media0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11723"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "unbind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=unbind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/2/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11724"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "unbind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=unbind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/1/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11725"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/1/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc01ip00in00"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11726"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_interface"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "INTERFACE=14/2/0"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MODALIAS=usb:v0BDAp5763d6728dcEFdsc02dp01ic0Eisc02ip00in01"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11727"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "unbind@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=unbind"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=189"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=6"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=bus/usb/001/007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_device"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "BUSNUM=001"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNUM=007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "remove@/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "ACTION=remove"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SUBSYSTEM=usb"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MAJOR=189"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "MINOR=6"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNAME=bus/usb/001/007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVTYPE=usb_device"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "PRODUCT=bda/5763/6728"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "TYPE=239/2/1"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "BUSNUM=001"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "DEVNUM=007"
[ ../testQSocketNotifier/devmonitor.cpp ] 123 slot_parseDeviceInfo   "SEQNUM=11729"
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`QSocketNotifier`是PyQt5中的一个类,用于在套接字上监视事件。它可以监视读取、写入和异常事件,并在这些事件发生时通知应用程序。 以下是使用`QSocketNotifier`的示例代码: ```python import socket from PyQt5.QtCore import QSocketNotifier, QObject, pyqtSignal class SocketReader(QObject): readyRead = pyqtSignal() def __init__(self, socket): super().__init__() self.notifier = QSocketNotifier(socket.fileno(), QSocketNotifier.Read) self.notifier.activated.connect(self.onActivated) def onActivated(self): self.readyRead.emit() ``` 在上面的代码中,我们首先创建了一个名为`SocketReader`的QObject子类。该类包含一个名为`readyRead`的PyQt信号,该信号在套接字上发生读取事件时发出。 在`__init__`方法中,我们创建了一个`QSocketNotifier`对象,并将其连接到`socket`的文件描述符上。我们指定了`QSocketNotifier.Read`作为事件类型,这表示我们只监视读取事件。最后,我们将`notifier`对象的`activated`信号连接到`onActivated`方法上。 `onActivated`方法在套接字上发生读取事件时被调用,并发出`readyRead`信号。 这样,我们就可以使用`SocketReader`类来监视套接字上的读取事件,如下所示: ```python # 创建套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 1234)) # 创建SocketReader对象 reader = SocketReader(sock) reader.readyRead.connect(onReadyRead) # 处理读取事件 def onReadyRead(): data = sock.recv(1024) print(data.decode()) ``` 在上面的代码中,我们首先创建一个套接字并连接到服务器。然后创建一个`SocketReader`对象,并将其`readyRead`信号连接到`onReadyRead`函数上。最后,我们定义了`onReadyRead`函数,该函数在套接字上发生读取事件时被调用,并打印接收到的数据。 这样,我们就可以使用`QSocketNotifier`类来监视套接字上的事件,并在事件发生时执行相应的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值