QT上的socket网络通信编程

        socket是一种实现网络不同主机进程通信的一种机制。根据是否面向连接,可以将socket通信分为面向连接的数据流和面向无连接的数据报通信。两者在实现的地方,有类似的地方:都需要创建相应的socket对象。但是,两者也有一定的区别。面向连接的TCP通信需要双方建立可行的数据连接后才能通信,而面向无连接的UDP通信则只是简单的将数据发送到对应的目标主机即可。

一、TCP通信编程流程

        面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。这个过程类似打电话,先拨号振铃,等待对方接听后,才能进行通话。在一个TCP连接中,仅有2方进行彼此通信,广播和多播不能用于TCP。

       首先,在linux上服务器端的工作流程:

       (1)建立socket对象,指定通信协议。

       (2)将创建的socket对象与当前主机的某个IP地址和端口绑定。

       (3)使socket对象处于监听状态,并设置监听队列的大小。

       客户端的工作流程:

       (1)建立socket对象,指定通信协议。

       (2)应用程序可以显式的绑定IP地址和端口。

       接着建立通信连接。

       (1)客户端向服务器发出连接请求。

       (2)服务器监听到该请求,并接受请求,从而建立连接。

       然后双方发送接收数据。

       通信完成后,双方都需要关闭socket对象。

在Qt中,对一些函数进行了封装。使用起来更方便。在Qt中的TCP服务器封装在QTcpServer这个类中,TCP客户端封装在QTcpSocket这个类中。

      Qt中TCP服务器的使用:

      (1)创建TCP服务器:

QTcpServer *tcpServer;
tcpServer = new QTcpServer(this);
      (2)TCP服务器监听:

tcpServer->listen(QHostAddress::Any,ui->txtPortServer->text().toInt() //ui->txtPortServer->text().toInt()是服务器的端口号
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnect()));
当有新的连接时,触发newConnect()函数。   

void MainWindow::newConnect()
{
    tcpClient = tcpServer->nextPendingConnection(); //得到每个连进来的socket
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(readMessageFromTCPClient())); //有可读的信息,触发读函数槽
}
当客户端向服务器发送数据的时候,准备接收数据。


Qt中TCP客户端的使用:

     (1)创建TCP客户端:

QTcpSocket *tcpClient;
tcpClient = new QTcpSocket(this);
    (2)TCP客户端连接服务器:
tcpClient->connectToHost(ui->txtIPServer->text(),ui->txtPortServer->text().toInt());//ui->txtIPServer->text()是服务器的IP地址   
//ui->txtPortServer->text().toInt()是服务器的端口号
connect(tcpClient,SIGNAL(readyRead()),this,SLOT(readMessageFromTCPServer()));
       TCP 客户端连接TCP服务器后,将客户端的readRead()信号和readMessageFromTCPServer()槽函数进行连接,准备读服务器发送过来的数据。

      然后双方发送接收数据:

      TCP服务器和TCP客户端的发送数据:

QString strMesg= ui->lineEdit->text();
tcpClient->write(strMesg.toStdString().c_str(),strlen(strMesg.toStdString().c_str())); //发送数据

      TCP服务器接收数据:

QByteArray qba= tcpClient->readAll(); //读取客户端发来的数据
      TCP客户端接收数据:

QByteArray qba= tcpClient->readAll(); //读取服务器发来的数据


二、UDP通信编程流程

       面向无连接的socket通信是不可靠传输,在通信前不需要建立可靠连接。双方实现数据他哦给那些的基本流程如下:

     首先,服务器工作流程:

     (1)建立socket对象,指定通信协议。

     (2)将创建的soket对象与某一个端口绑定。

     客户端工作流程:

      (1)建立socket对象,指定通信协议。

      (2) 将创建的soket对象与某一个端口绑定。

     接着通信双方进行数据传输。

     通信完成后,关闭socket对象。

在Qt中,对一些函数进行了封装。使用起来更方便。在Qt中的UDP服务器和客户端都封装在QUdpSocket这个类中。

      Qt中UDP服务器的使用:

      (1)创建UDP服务器:

QUdpSocket *udpServer; 
udpServer = new QUdpSocket(this);

      (2)绑定端口:

udpServer->bind(QHostAddress::Any,ui->txtPortServer->text().toInt(),QUdpSocket::ShareAddress);
connect(udpServer,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));
把udpServer的readRead信号和readPendingDatagrams()槽函数连接起来,当有数据过来的时候就执行槽函数。

    Qt中UDP客户端的使用:

     (1)创建UDP服务器:

QUdpSocket *udpClient; 
udpClient = new QUdpSocket(this);
     (2)绑定端口

udpClient->bind(QHostAddress::Any,ui->txtPortServerC->text().toInt(),QUdpSocket::ShareAddress);
connect(udpClient,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));
把udpClient的readRead信号和readPendingDatagrams()槽函数连接起来,当有数据过来的时候就执行槽函数。


      然后双方发送接收数据:

      UDP服务器发送数据:

udpServer->writeDatagram(strMesg.toAscii(), strMesg.length(),QHostAddress::Broadcast, senderPort);//UDP服务器向刚才接受到的data of client发送数据

     UDP客户端发送数据:

QHostAddress *ip;
ip = new QHostAddress(ui->txtIPServer->text());
udpClient->writeDatagram(strMesg.toAscii(),strMesg.length(),*ip, ui->txtPortServer->text().toInt());

      UDP服务器和客户端接收数据:

void MainWindow::readPendingDatagrams()
{
    QByteArray datagram;

    if(ui->rdbtnsever->isChecked())
    {
         datagram.resize(udpServer->pendingDatagramSize());
         while (udpServer->hasPendingDatagrams())
         {
             udpServer->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);  //读IP为sender,端口为senderPort的客户端数据
             qDebug()<<datagram;
             QString buf;
             buf = datagram;
             ui->textUdpServer->setText(buf);
             ui->label_5->setText("对方IP"+sender.toString());
         }
    }
    else if(ui->rdbtnclient->isChecked())
    {
        datagram.resize(udpClient->pendingDatagramSize());
        while(udpClient->hasPendingDatagrams())
        {
            udpClient->readDatagram(datagram.data(),datagram.size());
            qDebug()<<datagram;
            QString buf;
            buf = datagram;
            ui->textUdpClient->setText(buf);
        }
    }
}




  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值