一相关函数(QT += network)
1主机(本机)信息查询
一 QHostInfo类:
1 localHostName()函数:返回本机主机名
无参数,返回值QString类型的主机名称
1
| QString hostName=QHostInfo::localHostName();
|
2 fromName(QString &name)函数:返回指定的主机名的IP地址 参数:QString类型的主机名 返回值:指定的主机名QHostInfo类型的IP地址
1
| QHostInfo hostInfo=QHostInfo::fromName(hostName);
|
3 addresses()函数:返回与hostName()主机关联的IP地址列表[即QHostInfo类型转化成QList类型方便提取] 无参数,返回QList类型的ip列表(就是个数组每一条都是QHostAddress类型)
1
| QList<QHostAddress> addList=hostInfo.addresses();
|
4 QList 提取每条QHostAddress类型的数据:at(i)protocol()函数可以显示QHostAddress类型中的地址是ipv4还是ipv6toString()可以把QHostAddress类型转换成String类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| if (!addList.isEmpty())
for (int i=0;i<addList.count();i++) { QHostAddress aHost=addList.at(i); if (QAbstractSocket::IPv4Protocol==aHost.protocol()) { localIP=aHost.toString(); break; } }
|
二 QNetworkInterface类:
1. allInterfaces()函数:返回主机上所有接口的网络列表
无参数,返回值QList<QNetworkInterface>(QNetworkInterface类型的数组)
返回值包含QString类型的:
接口名称 :通过QNetworkInterfac的对象.humanReadableName()
硬件地址 :通过QNetworkInterfac的对象.hardwareAddress()
QList<QNetworkAddressEntry>类型的:
ip地址列表(包含ip,mac地址和 ): 通过QNetworkInterfac的对象.addressEntries()
2. .ip().toString()函数: 把QNetworkAddressEntry类型里的IP转化为String
3. .netmask().toString()函数:把QNetworkAddressEntry类型里的物理mac地址转化为String
4. .broadcast.toString()函数:把QNetworkAddressEntry类型里的广播地址转化为String
2.实现过程(服务端)
ui comboIP:监听地址
actStart:开始监听按钮
spinPort:监听端口按钮
btnSend:发送按钮
editMsg:消息发送文本框
1. 在mainwindow.h中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <QTcpSocket> #include <QLabel> private: QLabel *LabListen; QLabel *LabSocketState;
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
QString getLocalIP(); private slots:
void onNewConnection(); void onSocketStateChange(QAbstractSocket::SocketState socketState); void onClientConnected(); void onClientDisconnected(); void onSocketReadyRead();
void on_actStart_triggered();
void on_actStop_triggered();
void on_actClear_triggered();
void on_btnSend_clicked();
void on_actHostInfo_triggered();
|
2. 在mainwindow.cpp中(#include )
实现获取本地ip: 编写 getLocalIP()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| QString MainWindow::getLocalIP() { QString hostName=QHostInfo::localHostName(); QHostInfo hostInfo=QHostInfo::fromName(hostName); QString localIP=""; QList<QHostAddress> addList=hostInfo.addresses(); if (!addList.isEmpty()) for (int i=0;i<addList.count();i++) { QHostAddress aHost=addList.at(i); if (QAbstractSocket::IPv4Protocol==aHost.protocol()) { localIP=aHost.toString(); break; } } return localIP; }
|
构造函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); LabListen=new QLabel("监听状态:"); LabListen->setMinimumWidth(150); ui->statusBar->addWidget(LabListen); LabSocketState=new QLabel("Socket状态:"); LabSocketState->setMinimumWidth(200); ui->statusBar->addWidget(LabSocketState); QString localIP=getLocalIP(); this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP); ui->comboIP->addItem(localIP); tcpServer=new QTcpServer(this); connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection())); }
|
编写服务器监听函数 on_actStart_triggered();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| void MainWindow::on_actStart_triggered() { QString IP=ui->comboIP->currentText(); quint16 port=ui->spinPort->value(); QHostAddress addr(IP); tcpServer->listen(addr,port);
ui->plainTextEdit->appendPlainText("**开始监听..."); ui->plainTextEdit->appendPlainText("**服务器地址:" +tcpServer->serverAddress().toString()); ui->plainTextEdit->appendPlainText("**服务器端口:" +QString::number(tcpServer->serverPort())); ui->actStart->setEnabled(false); ui->actStop->setEnabled(true); LabListen->setText("监听状态:正在监听"); }
|
编写客户端启动连接时服务器该执行的函数onClientConnected()
1 2 3 4 5 6 7 8 9
| void MainWindow::onClientConnected() { ui->plainTextEdit->appendPlainText("**client socket connected"); ui->plainTextEdit->appendPlainText("**peer address:"+ tcpSocket->peerAddress().toString()); ui->plainTextEdit->appendPlainText("**peer port:"+ QString::number(tcpSocket->peerPort())); }
|
编写客户端断开连接时服务器该执行的函数onClientDisconnected()
1 2 3 4 5 6 7
| void MainWindow::onClientDisconnected() { ui->plainTextEdit->appendPlainText("**client socket disconnected"); tcpSocket->deleteLater(); }
|
编写客户端与服务器成功建立新连接时服务器该执行的函数onNewConnection()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void MainWindow::onNewConnection() {
tcpSocket = tcpServer->nextPendingConnection(); 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())); }
|
编写客户端与服务器socket状态改变该执行的函数onSocketStateChange(QAbstractSocket::SocketState socketState)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState) { switch(socketState) { case QAbstractSocket::UnconnectedState: LabSocketState->setText("scoket状态:UnconnectedState"); break; case QAbstractSocket::HostLookupState: LabSocketState->setText("scoket状态:HostLookupState"); break; case QAbstractSocket::ConnectingState: LabSocketState->setText("scoket状态:ConnectingState"); break; case QAbstractSocket::ConnectedState: LabSocketState->setText("scoket状态:ConnectedState"); break; case QAbstractSocket::BoundState: LabSocketState->setText("scoket状态:BoundState"); break; case QAbstractSocket::ClosingState: LabSocketState->setText("scoket状态:ClosingState"); break; case QAbstractSocket::ListeningState: LabSocketState->setText("scoket状态:ListeningState"); } }
|
编写自动读取Socket存放的消息的函数onSocketReadyRead()
1 2 3 4 5 6
| void MainWindow::onSocketReadyRead() {
while(tcpSocket->canReadLine()) ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readLine()); }
|
编写服务器停止监听函数 on_actStop_triggered();
1 2 3 4 5 6 7 8 9 10 11 12
| void MainWindow::on_actStop_triggered() { if (tcpServer->isListening()) { tcpServer->close(); ui->actStart->setEnabled(true); ui->actStop->setEnabled(false); LabListen->setText("监听状态:已停止监听"); } }
|
编写发送函数 on_btnSend_clicked()//收发协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void MainWindow::on_btnSend_clicked() { QString msg=ui->editMsg->text(); ui->plainTextEdit->appendPlainText("[out] "+msg); ui->editMsg->clear(); ui->editMsg->setFocus(); QByteArray str=msg.toUtf8(); str.append('\n'); tcpSocket->write(str); }
|
3.实现过程(客户端)
ui comboServer:服务器地址文本框(里面是自己填的不是传输得到的)
actConnect:连接服务器按钮
spinPort:需要连接的服务器端口文本框((里面是自己填的不是传输得到的))
actDisconnect:断开服务器按钮
btnSend:发送按钮
editMsg:消息发送文本框
1. 在mainwindow.h中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <QTcpSocket> #include <QLabel> private: QTcpSocket *tcpClient; QLabel *LabSocketState; QString getLocalIP(); protected: void closeEvent(QCloseEvent *event); private slots:
void onConnected(); void onDisconnected(); void onSocketStateChange(QAbstractSocket::SocketState socketState); void onSocketReadyRead();
void on_actConnect_triggered();
void on_actDisconnect_triggered();
void on_actClear_triggered();
void on_btnSend_clicked();
|
2. 在mainwindow.cpp中
#include <QHostAddress>
#include <QHostInfo>)
实现获取本地ip: 编写 getLocalIP()
构造函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); tcpClient=new QTcpSocket(this); LabSocketState=new QLabel("Socket状态:"); LabSocketState->setMinimumWidth(250); ui->statusBar->addWidget(LabSocketState); QString localIP=getLocalIP(); this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
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())); }
|
编写客户端按下启动连接时该执行的函数on_actConnect_triggered()
1 2 3 4 5 6 7 8 9 10 11
| void MainWindow::on_actConnect_triggered() { QString addr=ui->comboServer->currentText(); quint16 port=ui->spinPort->value(); tcpClient->connectToHost(addr,port);
}
|
编写客户端无法连接时该执行的函数onDisconnected()
1 2 3 4 5 6 7
| void MainWindow::onDisconnected() { ui->plainTextEdit->appendPlainText("**已断开与服务器的连接"); ui->actConnect->setEnabled(true); ui->actDisconnect->setEnabled(false); }
|
编写客户端成功连接时该执行的函数onConnected()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void MainWindow::onConnected() { ui->plainTextEdit->appendPlainText("**已连接到服务器"); ui->plainTextEdit->appendPlainText("**peer address:"+ tcpClient->peerAddress().toString()); ui->plainTextEdit->appendPlainText("**peer port:"+ QString::number(tcpClient->peerPort())); ui->actConnect->setEnabled(false); ui->actDisconnect->setEnabled(true); }
|
编写客户端按下断开连接时该执行的函数on_actDisconnect_triggered()
1 2 3 4 5 6 7
| void MainWindow::on_actDisconnect_triggered() { if (tcpClient->state()==QAbstractSocket::ConnectedState) tcpClient->disconnectFromHost(); }
|
编写客户端自动读取socket里的消息的函数onSocketReadyRead()
1 2 3 4 5 6
| void MainWindow::onSocketReadyRead() { while(tcpClient->canReadLine()) ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine()); }
|
编写发送函数 on_btnSend_clicked()//收发协议
1 2 3 4 5 6 7 8 9 10 11
| void MainWindow::on_btnSend_clicked() { QString msg=ui->editMsg->text(); ui->plainTextEdit->appendPlainText("[out] "+msg); ui->editMsg->clear(); ui->editMsg->setFocus();
QByteArray str=msg.toUtf8(); str.append('\n'); tcpClient->write(str); }
|
编写清空文本函数on_actClear_triggered()
1 2 3 4
| void MainWindow::on_actClear_triggered() { ui->plainTextEdit->clear(); }
|
总结
服务端(QTcpServer *tcpServer; //TCP服务器(实例化一个服务器对象))
1.先获取本机ip
2.服务器监听本机ip和某个端口(自己写的):tcpServer->listen(addr,port);
3.服务器开始监听后收到信号会自动连接,成功后会自动产生newConnection()信号)一旦连接服务器对象连接成功执行槽函数onNewConnectio()
1.建立服务器的socket:tcpSocket = tcpServer->nextPendingConnection();
2.自动连接成功后服务器的socket自动产生connected()信号执行槽函数onNewConnectio()
3.连接断开时服务器Socket自动产生disconnected()信号执行槽函数onClientDisconnected()
4.socket状态改变时Socket自动产生stateChanged信号执行槽函数onSocketStateChange
5.完成连接后一旦Socket里写入信息自动产生readyRead()信号 执行槽函数onSocketReadyRead()读Socket里的信息
6.发送消息就是往socket里写数据: tcpSocket->write(str);
4.停止监听 :tcpServer->close();
客户端(QTcpSocket *tcpClient; //使用socket实例化一个里客户端对象)
1.使用socket实例化一个里客户端对象(客户端本身就是个socket)tcpClient=new QTcpSocket(this);
2.获取本机ip编写
3.客户端根据地址和端口(自己写的要连接的服务器ip和端口)连接到主机(qt自带的):套接字实例化的客户端使用qt的connectToHost函数可以自动连接到某个服务器
4.自动连接成功后客户端自动产生connected()信号执行槽函数onConnected()
5.完成连接后一旦Socket里写入信息自动产生readyRead()信号 执行槽函数onSocketReadyRead()读Socket里的信息
6.连接失败自动产生disconnected()信号,执行onDisconnected()槽函数
7.连接状态改变自动产生stateChanged(QAbstractSocket::SocketState)信号,执行onSocketStateChange(QAbstractSocket::SocketState))槽函数
8.发送消息就是往socket里写数据:tcpClient->write(str);
9.停止连接: 客户段断开与主机的联系(qt自带disconnectFromHost()):tcpClient->disconnectFromHost();
注意:
服务端的ip是获取本机ip得到的,端口自己写的;
客户端要连接哪个服务器的哪个端口是自己写的 :
建立连接后由于是同类了,可以通过套接字里的peer查看对方的ip和端口;
服务器查看客户端的:
IP: tcpSocket->peerAddress().toString()
端口:QString::number(tcpSocket->peerPort())
客户端查看服务器的:
ip: tcpClient->peerAddress().toString()
端口:QString::number(tcpClient->peerPort())
源码:
链接:https://pan.baidu.com/s/1xqtD4-d9SbWwVlFMMrLxEg?pwd=sjii
提取码:sjii