Qt项目实战--网络编程简单BC端聊天系统

项目介绍

基于TCP的客户端聊天系统,客户端连接服务器ip成功后,即可与服务器之间通讯。详细说明见下文。
在这里插入图片描述

相关知识点

开发工具为QT, 具有网络功能的程序需要在pro文件中添加“QT += network”。

QHostInfo

QHostInfo类为主机名查找提供了静态函数。这个类提供了两个方便的静态函数:一个异步工作并在找到主机时发出信号另一个阻塞并返回QHostInfo对象。

异步查找主机的IP地址,调用lookupHost(),它接受主机名或IP地址、接收方对象和槽签名作为参数并返回ID。 您可以通过使用查找ID调用abortHostLookup()来中止查找。

//通过域名查找ip
QHostInfo::lookupHost("www.baidu.com",this,[](const QHostInfo& info)
{
    qDebug()<<info.hostName()<<info.addresses();
});
//查找ip是否存在
QHostInfo::lookupHost("183.232.231.172",this,[](const QHostInfo& info)
{
    qDebug()<<info.hostName()<<info.addresses();
});

当结果准备好时,将调用该槽。 结果存储在QHostInfo对象中。 调用addresses()获取主机的IP地址列表,调用hostName()获取所查找的主机名。
如果查找失败,error()将返回所发生的错误类型。 errorString()给出了可读的查找错误描述。
要一个阻塞查找,使用QHostInfo::fromName()函数:

QHostInfo info = QHostInfo::fromName("smtp.qq.com");
qDebug()<<info.hostName()<<info.addresses();

QHostAddress

此类以独立于平台和协议的方式保存IPv4或IPv6地址址.
在这里插入图片描述

QAbstractSocket

QAbstractSocket类提供了所有套接字类型通用的基本功能 。AbstractSocket是QTcpSocket和QUdpSocket的基类,包含这两个类的所有通用功能。

QTcpSocket

QTcpSocket类提供一个TCP套接字.

QTcpSocket *tcpSocket = new QTcpSocket(this);
tcpSocket->connectToHost("127.0.0.1",8888);

//此信号在调用connectToHost()并成功建立连接后发出。  
void connected()
//这个信号在套接字被断开时发出。      
void disconnected()
//此信号在发生错误后发出。当发出此信号时,套接字可能还没有准备好重新连接。 在这种情况下,尝试重新连接应该从事件循环中完成。 例如,使用带有0作为超时的QTimer::singleShot()。   
void error(QAbstractSocket::SocketError socketError)
//在调用connectToHost()并成功查找主机之后,将发出此信号。    
void hostFound()
//每当有新的数据可以从设备的当前读取通道读取时,就会发出此信号。    
void readyRead()

QUdpSocket

UDP(用户数据报协议)是一种轻量级、不可靠、面向数据报、无连接的协议。 当可靠性不重要时,可以使用它。 QUdpSocket是QAbstractSocket的一个子类,允许您发送和接收UDP数据报。

使用该类最常见的方法是使用bind()绑定到一个地址和端口,然后调用writeDatagram()和readDatagram() / receiveDatagram()来传输数据。 如果你想使用标准的QIODevice函数read(), readLine(), write()等,你必须首先通过调用connectToHost()将套接字直接连接到对等体。
套接字在每次将数据报写入网络时发出bytesWritten()信号。 如果您只是想发送数据报,则不需要调用bind()。

readyRead()信号在数据报到达时被触发。 在这种情况下,hasPendingDatagrams()返回true。 调用pendingDatagramSize()获取第一个挂起的数据报的大小,并调用readDatagram()或receiveDatagram()读取它。

QTcpServer

QTcpServer类提供了一个基于tcp的服务器。

这个类使接收传入的TCP连接成为可能。 您可以指定端口或让QTcpServer自动选择一个端口。 您可以监听一个特定的地址或所有机器的地址。

调用listen()让服务器监听传入的连接。 然后,每当客户机连接到服务器时,就会发出newConnection()信号。 调用nextPendingConnection()接受挂起的连接作为已连接的QTcpSocket。 该函数返回一个指向QAbstractSocket::ConnectedState中的QTcpSocket的指针,您可以使用该指针与客户端通信。

Server::Server(QObject *parent) : QObject(parent)
{
    m_tcpServer = new QTcpServer(this);
    m_tcpServer->listen(QHostAddress::Any,6666);
    connect(m_tcpServer,&QTcpServer::acceptError,this,&Server::onAcceptError);
    connect(m_tcpServer,&QTcpServer::newConnection,this,&Server::onNewConnection);
}
void Server::onAcceptError(QAbstractSocket::SocketError socketErr)
{
    qDebug()<<"hasError"<<socketErr;
}

void Server::onNewConnection()
{
    qDebug()<<"newConnection";
    //获取下一个待处理的连接
    QTcpSocket* tcpSocket = m_tcpServer->nextPendingConnection();
    m_tcps.push_back(tcpSocket);
    tcpSocket->write("hello");
    qDebug()<<m_tcps.size();
    connect(tcpSocket,&QTcpSocket::readyRead,this,&Server::onReadyRead);
}

void Server::onReadyRead()
{
    QTcpSocket *tcpsokcet = dynamic_cast<QTcpSocket*>(sender());
    if(tcpsokcet)
    {
         qDebug() <<"server"<<QHostAddress(tcpsokcet->peerAddress().toIPv4Address()).toString()<<tcpsokcet->peerName()<<tcpsokcet->peerPort();
    }
}
常用函数
//服务器开始监听指定addres和port上的连接,有新链接发出newConnection()信号
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//将下一个挂起的连接作为已连接的QTcpSocket对象返回。  在 newConnection()的槽函数中使用
virtual QTcpSocket *nextPendingConnection()


//当接受新连接导致错误时将发出此信号。 socketError参数描述了发生的错误类型。  
[signals] void acceptError(QAbstractSocket::SocketError socketError)
//每当有新连接可用时,就会发出此信号。      
[signals] void newConnection()   

项目展示

项目代码已上传至博客。博客gitee
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Warm wolf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值