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;
}
}
运行结果:
控制台输出结果如下: