1 新建一个项目:TCPServer.pro
A 修改TCPServer.pro,注意:如果是想使用网络库,需要加上network
SOURCES += \
TcpServer.cpp \
TcpClient.cpp
HEADERS += \
TcpServer.h \
TcpClient.h
QT += gui widgets network
CONFIG += C++11
B 新建如下文件,因为要用到网络库,所以加上network
C 编写IP选择下拉选,头文件ChooseInterface.h
#ifndef CHOOSEINTERFACE_H
#define CHOOSEINTERFACE_H
#include <QDialog>
#include <QComboBox>
class ChooseInterface : public QDialog
{
Q_OBJECT
public:
explicit ChooseInterface(QWidget *parent = 0);
QComboBox* _comboBox;
QString _strSelect;
signals:
public slots:
void slotComboBoxChange(QString);
};
#endif // CHOOSEINTERFACE_H
编写ChooseInterface.cpp
#include "ChooseInterface.h"
#include <QNetworkInterface>
#include <QVBoxLayout>
ChooseInterface::ChooseInterface(QWidget *parent) :
QDialog(parent)
{
/* get all interface */
QList<QHostAddress> addrList = QNetworkInterface::allAddresses();
#if 0
QList<QNetworkInterface> infList = QNetworkInterface::allInterfaces();
QList<QNetworkAddressEntry> entryList = infList.at(0).addressEntries();
entryList.at(0).broadcast()
#endif
//编写一个下拉选
_comboBox = new QComboBox;
QVBoxLayout* lay = new QVBoxLayout(this);
lay->addWidget(_comboBox);
foreach(QHostAddress addr, addrList)
{
//将地址都转换成为ipv4的地址
quint32 ipaddr = addr.toIPv4Address();
//去掉0的ip
if(ipaddr == 0)
continue;
//在comboBox中添加下拉选
_comboBox->addItem(QHostAddress(ipaddr).toString());
}
//当下拉选发生变化时的操作
connect(_comboBox, SIGNAL(currentIndexChanged(QString)),
this, SLOT(slotComboBoxChange(QString)));
}
void ChooseInterface::slotComboBoxChange(QString str)
{
this->_strSelect = str;
}
上面的运行结果是:
编写TcpServer.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextBrowser>
class TcpServer:public QWidget
{
Q_OBJECT
public:
explicit TcpServer(QWidget *parent = 0);
QTcpServer* _server;
QTcpSocket* _socket;
QTextBrowser* _show;
signals:
public slots:
void slotNetConnection();
void slotReadyRead();
};
#endif // TCPSERVER_H
编写TcpServer.cpp
#include "TcpServer.h"
#include <QHBoxLayout>
#include <QNetworkInterface>
#include <QMessageBox>
#include "ChooseInterface.h"
TcpServer::TcpServer(QWidget *parent) :
QWidget(parent)
{
// 创建服务器并监听
_server = new QTcpServer;
ChooseInterface dlg;
dlg.exec();
//消息提示框
QMessageBox::information(NULL,"you select the ip:", dlg._strSelect);
_server->listen(QHostAddress(dlg._strSelect), 9988);
// 当有客户端来连接时,调用slotNetConnection方法
connect(_server, SIGNAL(newConnection()),
this, SLOT(slotNetConnection()));
_show = new QTextBrowser;
QHBoxLayout* lay = new QHBoxLayout(this);
lay->addWidget(_show);
}
void TcpServer::slotNetConnection()
{
// 判断是否有未处理的连接
while(_server->hasPendingConnections())
{
// 调用nextPeddingConnection去获得连接的socket
_socket = _server->nextPendingConnection();
_show->append("New connection ....");
// 为新的socket提供槽函数,来接收数据
connect(_socket, SIGNAL(readyRead()),
this, SLOT(slotReadyRead()));
}
}
void TcpServer::slotReadyRead()
{
// 接收数据,判断是否有数据,如果有,通过readAll函数获取所有数据
while(_socket->bytesAvailable() > 0)
{
_show->append("Data arrived ..... ");
QByteArray buf = _socket->readAll();
_show->append(buf);
}
}
编写TcpClient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QWidget>
#include <QTcpSocket>
#include <QLineEdit>
class TcpClient:public QWidget
{
Q_OBJECT
public:
explicit TcpClient(QWidget *parent = 0);
QTcpSocket* _socket;
QLineEdit* _lineEdit;
signals:
public slots:
void slotButtonClick();
};
#endif // TCPCLIENT_H
编写TcpClient.cpp
#include "TcpClient.h"
#include <QHBoxLayout>
#include <QPushButton>
TcpClient::TcpClient(QWidget *parent):
QWidget(parent)
{
_socket = new QTcpSocket(this);
_socket->connectToHost("127.0.0.1", 9988);
_lineEdit = new QLineEdit;
QHBoxLayout* lay = new QHBoxLayout(this);
lay->addWidget(_lineEdit);
QPushButton* button = new QPushButton("Send");
lay->addWidget(button);
connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClick()));
connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(slotButtonClick()));
}
void TcpClient::slotButtonClick()
{
QString strText = _lineEdit->text();
if(strText.isEmpty())
return;
_socket->write(strText.toUtf8());
_lineEdit->clear();
}
MyWidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
signals:
public slots:
};
#endif // MYWIDGET_H
MyWidget.cpp
#include "MyWidget.h"
#include <QApplication>
#include "TcpServer.h"
#include "TcpClient.h"
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
}
int main(int argc,char** argv)
{
QApplication app(argc,argv);
TcpServer s; s.show();
TcpClient c; c.show();
s.setWindowTitle("server");
c.setWindowTitle("client");
return app.exec();
}
运行结果:
2 编写UDP程序
UDPServer.pro
QT += gui widgets network
CONFIG += C++11
HEADERS += \
Udp1.h \
Udp2.h \
MyWidget.h
SOURCES += \
Udp1.cpp \
Udp2.cpp \
MyWidget.cpp
Udp1.h
#ifndef UDP1_H
#define UDP1_H
#include <QWidget>
#include <QUdpSocket>
class Udp1 : public QWidget
{
Q_OBJECT
public:
explicit Udp1(QWidget *parent = 0);
QUdpSocket* _udp;
signals:
public slots:
void slotReadyRead();
};
#endif // UDP1_H
Udp1.cpp
#include "udp1.h"
#include <QTimer>
#include <QDateTime>
Udp1::Udp1(QWidget *parent) :
QWidget(parent)
{
// 创建udpsocket,并连接槽函数,用来接收数据
_udp = new QUdpSocket;
_udp->bind(10001);
connect(_udp, SIGNAL(readyRead()),
this, SLOT(slotReadyRead()));
// 使用定时器来定时发送时间戳
QTimer* timer = new QTimer;
timer->setInterval(1000);
timer->start();
connect(timer, &QTimer::timeout, [&](){
quint64 timestamp = QDateTime::currentMSecsSinceEpoch();
QString str = QString::number(timestamp);
#if 0
// 普通UDPsocket发送
_udp->writeDatagram(str.toUtf8(), QHostAddress("127.0.0.1"), 10002);
#else
// 广播发送,注意:QHostAddress::Broadcast是255.255.255.255, 192.168.6.255
// _udp->writeDatagram(str.toUtf8(), QHostAddress::Broadcast, 10002);
// multicast, 224.0.0.1~224.0.0.255 is multicast address of LAN
_udp->writeDatagram(str.toUtf8(), QHostAddress("224.0.0.131"), 10002);
#endif
});
}
void Udp1::slotReadyRead()
{
while(_udp->hasPendingDatagrams())
{
quint32 datagramSize = _udp->pendingDatagramSize();
QByteArray buf(datagramSize, 0);
_udp->readDatagram(buf.data(), buf.size());
qDebug() <<"Udp1"<< buf;
}
}
Udp2.h
#ifndef UDP2_H
#define UDP2_H
#include <QWidget>
#include <QUdpSocket>
class Udp2 : public QWidget
{
Q_OBJECT
public:
explicit Udp2(QWidget *parent = 0);
QUdpSocket* _udp;
signals:
public slots:
void slotReadyRead();
};
#endif // UDP2_H
Udp2.cpp
#include "udp2.h"
#include <QTimer>
#include <QDateTime>
#include <QLineEdit>
Udp2::Udp2(QWidget *parent) :
QWidget(parent)
{
_udp = new QUdpSocket;
// the address of bind and multicast must be same tpye(IPV4 or IPV6)
_udp->bind(QHostAddress::AnyIPv4, 10002);
// join the multicast address (224.0.0.131) for recv mulicast package
_udp->joinMulticastGroup(QHostAddress("224.0.0.131"));
connect(_udp, SIGNAL(readyRead()),
this, SLOT(slotReadyRead()));
QTimer* timer = new QTimer(this);
timer->setInterval(1000);
timer->start();
connect(timer, &QTimer::timeout, [&](){
quint64 timestamp = QDateTime::currentMSecsSinceEpoch();
QString str = QString::number(timestamp);
_udp->writeDatagram(str.toUtf8(), QHostAddress("127.0.0.1"), 10001);
});
}
void Udp2::slotReadyRead()
{
while(_udp->hasPendingDatagrams())
{
quint32 datagramSize = _udp->pendingDatagramSize();
QByteArray buf(datagramSize, 0);
_udp->readDatagram(buf.data(), buf.size());
qDebug() << "Udp2" <<buf;
}
}
运行结果:
控制台输出结果如下: