使用Qt网络模块,需要在配置文件中添加Qt += network
方法 | 描述 |
---|---|
QList addresses() const; | 获取与主机名关联的IP地址列表 |
HostInfoError error() const; | 如果主机查找失败,返回失败类型 |
QString errorString() const; | 如果主机查找失败,返回错误描述字符串 |
QString hostName() const; | 通过IP地址查找的主机的名称 |
int lookupId() const; | 返回本次查找的ID |
静态函数 | 描述 |
---|---|
static void abortHostLookup(int lookupId); | 中断主机查找 |
static QHostInfo fromName(const QString &name); | 获取指定主机名的IP地址 |
static QString localDomainName(); | 获取本机DNS域名 |
static QString localHostName(); | 获取本机主机名 |
static int lookupHost(const QString &name, QObject *receiver, const char *member); | 以异步方式根据主机名查找主机IP地址,并返回一个表示本次查找的ID,可用于abortHostLookup |
//获取本机的IP
void Dialog::GetQHostInfo()
{
QString hostName=QHostInfo::localHostName();//本地主机名
QHostInfo hostInfo=QHostInfo::fromName(hostName); //本机IP地址
QList<QHostAddress> addList=hostInfo.addresses();//IP地址列表
if (!addList.isEmpty())
{
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);//每一项是一个QHostAddress
aHost.protocol(); //协议类型
aHost.toString(); //本机IP地址
}
}
}
//协议类型,aHost.protocol();返回值
enum NetworkLayerProtocol {
IPv4Protocol,
IPv6Protocol,
AnyIPProtocol,
UnknownNetworkLayerProtocol = -1
};
//查找主机信息的槽函数
void Dialog::lookedUpHostInfo(const QHostInfo &host)
{
QList<QHostAddress> addList=host.addresses();//
if (!addList.isEmpty())
{
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);//每一项是一个QHostAddress
aHost.protocol(); //协议类型
aHost.toString(); //本机IP地址
}
}
}
//参数name可以是www.163.com或者本机名QHostInfo::localHostName()
//以异步方式根据主机名查找主机IP地址
void Dialog::Lookup(const QString &name)
{
QHostInfo::lookupHost(name, this,SLOT(lookedUpHostInfo(QHostInfo)));
}
方法 | 描述 |
---|---|
QList QNetworkInterface::addressEntries() const; | 返回该网络接口的IP地址列表(包括子网掩码和广播地址) |
QString QNetworkInterface::hardwareAddress() const; | 返回改接口的地基硬件地址,以太网里面是MAC地址 |
QString QNetworkInterface::humanReadableName() const; | 设备名称 |
bool QNetworkInterface::isValid() const; | 判断接口是否有效 |
QString QNetworkInterface::name() const; | 网络接口名称 |
方法 | 描述 |
---|---|
static QList allAddresses(); | 返回主机上所有IP地址的列表 |
static QList allInterfaces(); | 返回主机上所有接口的网络列表 |
//QNetworkInterface::allAddresses()的使用
void Dialog::on_btnDetail_clicked()
{
QList<QHostAddress> addList=QNetworkInterface::allAddresses();
if (!addList.isEmpty())
{
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
aHost.protocol(); //协议类型
aHost.toString(); //本机IP地址
}
}
}
//QNetworkInterface::allInterfaces()函数的使用
void Dialog::on_btnALLInterface_clicked()
{
QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
for(int i=0;i<list.count();i++)
{
QNetworkInterface aInterface=list.at(i);
if (!aInterface.isValid())
continue;
aInterface.humanReadableName();//设备名称
aInterface.hardwareAddress();//硬件地址
QList<QNetworkAddressEntry> entryList=aInterface.addressEntries();
for(int j=0;j<entryList.count();j++)
{
QNetworkAddressEntry aEntry=entryList.at(j);
aEntry.ip().toString();//IP 地址
aEntry.netmask().toString();//子网掩码
aEntry.broadcast().toString();//广播地址
}
}
}
方法 | 描述 |
---|---|
void close(); | 关闭服务器,停止网络监听 |
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0); | 监听指定IP和端口,成功返回true |
bool isListening() const; | 服务器处于监听状态,true表示正在监听 |
quint16 serverPort() const; | 如果服务器在监听状态,返回服务器端口 |
QHostAddress serverAddress() const; | 如果服务器在监听状态,返回服务器地址 |
bool waitForNewConnection(int msec = 0, bool *timedOut = nullptr); | 以阻塞的方式等待新的连接 |
virtual QTcpSocket *nextPendingConnection(); | 返回下一个等待接入的连接 |
信号 | 描述 |
---|---|
void newConnection(); | 当有新的连接是发射此信号 |
void acceptError(QAbstractSocket::SocketError socketError); | 当接受一个新的连接发生错误时,发射此信号,参数描述了错误信息 |
方法 | 描述 |
---|---|
void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol) override; | 以异步方式连接到指定IP和端口的TCP服务器,连接成功会发射connected()信号 |
void disconnectFromHost() override; | 断开socket连接,断开成功后发射sidconnected()信号 |
bool waitForConnected(int msecs = 30000) override; | 等待直到建立socket连接 |
bool waitForDisconnected(int msecs = 30000) override; | 等待直到断开socket连接 |
quint16 localPort() const; | 返回本socket的端口 |
QHostAddress localAddress() const; | 返回本socket的地址 |
quint16 peerPort() const; | 已经连接状态下返回对方端口 |
QHostAddress peerAddress() const; | 已经连接状态下返回对方地址 |
QString peerName() const; | 已经连接状态下返回对方主机名 |
SocketState state() const; | 返回socket的当前状态 |
bool canReadLine() const override; | 如果有行数据要从socket缓冲区读取就返回true |
qint64 write(const QByteArray &data) | 发送消息 |
信号 | 描述 |
---|---|
void connected(); | connectToHost成功连接到服务器后发射此信号 |
void disconnected(); | 当断开socket连接时发射此信号 |
void stateChanged(QAbstractSocket::SocketState); | 当socket状态发生变化时发射此信号 |
void error(QAbstractSocket::SocketError); | 当socket发生错误时发射此信号 |
void hostFound(); | 调用connectToHost找到主机后发射此信号 |
void readyRead(); | 当缓冲区有新数据需要读取时发射此信号,在此信号的槽函数里面读取数据 |
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
tcpClient=new QTcpSocket(this); //创建socket变量
connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));
connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
connect(tcpClient,SIGNAL(readyRead()),
this,SLOT(onSocketReadyRead()));
}
//connected()信号槽函数
void MainWindow::onConnected()
{
tcpClient->peerAddress().toString();
tcpClient->peerPort();
}
//disConnected()信号槽函数
void MainWindow::onDisconnected()
{
}
//readyRead()信号槽函数
void MainWindow::onSocketReadyRead()
{
while(tcpClient->canReadLine())
QByteArray str = tcpClient->readLine();
}
//连接到服务器
void MainWindow::on_actConnect_triggered(const QHostAddress &address, quint16 port)
{
tcpClient->connectToHost(address,port);
}
//断开与服务器的连接
void MainWindow::on_actDisconnect_triggered()
{
if (tcpClient->state()==QAbstractSocket::ConnectedState)
tcpClient->disconnectFromHost();
}
//发送数据
void MainWindow::on_btnSend_clicked()
{
QString msg="I am God";
QByteArray str=msg.toUtf8();
str.append('\n');
tcpClient->write(str);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
tcpServer=new QTcpServer(this);
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}
//开始监听
void MainWindow::on_actStart_triggered()
{
QString IP=ui->comboIP->currentText();//IP地址
quint16 port=ui->spinPort->value();//端口
QHostAddress addr(IP);
tcpServer->listen(addr,port);//
//tcpServer->listen(QHostAddress::Any, port);
tcpServer->serverAddress().toString();//服务器地址
tcpServer->serverPort();//服务器端口
}
//停止监听
void MainWindow::on_actStop_triggered()
{
if (tcpServer->isListening()) //tcpServer正在监听
{
tcpServer->close();//停止监听
}
}
//关闭窗口时停止监听
void MainWindow::closeEvent(QCloseEvent *event)
{
if (tcpServer->isListening())
tcpServer->close();//停止网络监听
event->accept();
}
//有新连接
void MainWindow::onNewConnection()
{
tcpSocket = tcpServer->nextPendingConnection(); //创建socket
connect(tcpSocket, SIGNAL(connected()),
this, SLOT(onClientConnected()));
onClientConnected();//
connect(tcpSocket, SIGNAL(disconnected()),
this, SLOT(onClientDisconnected()));
connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
onSocketStateChange(tcpSocket->state());
connect(tcpSocket,SIGNAL(readyRead()),
this,SLOT(onSocketReadyRead()));
}
//客户端接入时
void MainWindow::onClientConnected()
{
tcpSocket->peerAddress().toString();//客户端地址
tcpSocket->peerPort();//客户端端口
}
//客户端断开连接时
void MainWindow::onClientDisconnected()
{
tcpSocket->deleteLater();
}
//读取缓冲区行文本
void MainWindow::onSocketReadyRead()
{
while(tcpSocket->canReadLine())
ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readLine());
}
//发送一行字符串,以换行符结束
void MainWindow::on_btnSend_clicked()
{
QString msg="I am God";
QByteArray str=msg.toUtf8();
str.append('\n');//添加一个换行符
tcpSocket->write(str);
}
QHostAddress定义了集中特殊的IP地址,如
QHostAddress::Null表示一个空地址;
QHostAddress::LocalHost表示IPv4的本机地址127.0.0.1;
QHostAddress::LocalHostIPv6表示IPv6的本机地址;
QHostAddress::Broadcast表示广播地址255.255.255.255;
QHostAddress::Any表示IPv4的任意地址;
QHostAddress::AnyIPv6表示IPv6的任意地址。