windows下QT前台和linux下后台程序通过socket通信

作者:冯老师,华清远见教育科技集团讲师。

通常情况下,linux下的后台程序不需要GUI进行展示,而前台程序往往有个界面,方便和用户的交互。本文所演示的例子,是QT 程序和后台linux进程(C语言)交互,通过socket传输的内容是结构体。因为QT本身是跨平台的框架,因此以后前端程序移植到其它平台依然能很好的运行。

结构体的定义如下:

struct Test
        {
                int a;
                char b;
        };

QT程序:windows系统,使用QT提供的服务器类QTCPServer 、QTcpSocket和相关函数。

linux下的C程序:通过linux提供的socket编程接口,连接服务器,并发送结构体。

QT程序的关键代码如下:

void TcpServerDemo::on_listenButton_clicked()
        {
                this->tcpServer = new TcpServer(this);

                QString ip;
                ip = ui->ipLineEdit->text();
                QString port ;
                port = ui->portLineEdit->text();

                if (! this->tcpServer->listen(QHostAddress(ip), (quint16)(port.toInt())))
                {
                        QMessageBox::warning(this, tr("tcp server"),
                        tr("listen error:%1").arg(this->tcpServer->errorString()));
                        return;
                }
                ui->listenButton->setEnabled(false);
        }

        void TcpServer::incomingConnection ( int socketDescriptor )
        {
                this->tcpSocket = new QTcpSocket(this);
                this->tcpSocket->setSocketDescriptor(socketDescriptor);
                QObject::connect(this->tcpSocket, SIGNAL(readyRead()),
                this, SLOT(on_ready_read()));
        }

void TcpServer::on_ready_read()
        {
                struct Test t;
                this->tcpSocket->read((char *)&t,sizeof(t));
                QMessageBox::warning(NULL, tr("tcp server"),
                tr("a=%1 b=%2").arg(t.a).arg(t.b));
        }

linux下C程序的关键代码:

int sockfd;
        struct sockaddr_in servaddr;//, myaddr;
        struct Test* p;
        char buf[N] = {0};
        ssize_t n;
        if (argc != 3)
        {
                printf("usage:%s serverip serverport\n", argv[0]);
                return 0;
        }
        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket");
                return -1;
        }
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = PF_INET;
        servaddr.sin_port = htons(atoi(argv[2]));//error htons("6000");
        servaddr.sin_addr.s_addr = inet_addr(argv[1]);
        if (-1 == connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
        {
                perror("connect");
                return -1;
        }
        p = (struct Test *)buf;
        printf("input a b:");
        scanf("%d", &p->a);
        getchar();
        scanf("%c", &p->b);
        printf("a=%d b=%d\n", p->a, p->b);
        if (-1 == send(sockfd, p, sizeof(buf), 0))
        {
                perror("send");
                return -1;
        }
        memset(buf, 0, N);
        if ((n = recv(sockfd, buf, N, 0)) == -1)
        {
                perror("recv");
                return -1;
        }
        p = (struct Test *)buf;
        printf("a=%d b=%c", p->a, p->b);
        printf(">");
        close(sockfd);