5.关于QT中的网络编程,QTcpSocket,QUdpSocket



1
新建一个项目:TCPServer.pro


修改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();

}

运行结果:


编写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;

   
}

}

运行结果:

控制台输出结果如下:

 

时间: 2024-10-02 18:32:49

5.关于QT中的网络编程,QTcpSocket,QUdpSocket的相关文章

《Python核心编程(第3版)》——2.4 Python中的网络编程

2.4 Python中的网络编程 既然你知道了所有关于客户端/服务器架构.套接字和网络方面的基础知识,接下来就让我们试着将这些概念应用到Python中.本节中将使用的主要模块就是socket模块,在这个模块中可以找到socket()函数,该函数用于创建套接字对象.套接字也有自己的方法集,这些方法可以实现基于套接字的网络通信. 2.4.1 socket()模块函数 要创建套接字,必须使用socket.socket()函数,它一般的语法如下. socket(socket_family, socket

QT分析之网络编程(一)

首先对Windows下的网络编程总结一下: 如果是服务器,其WinSDK调用分别为: WSAStartup() -> socket() -> htons() / htonl() -> bind() -> listen() -> accept() -> recv() / send() -> closesocket() -> WSACleanup() 如果是客户端程序,其调用序列为: WSAStartup() -> socket() -> htons

Linux系统下QT中的多线程编程

Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能.为了满足 用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持. Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能.为了满足 用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持.从 2.2 版本开始,Qt 主要从下 面三个方面对多线程编程提供支持:一.构造了一些基本的与平台无关的线程类:二.提交用户自定义事 件的 Thread-saf

Java中的网络编程

​ Java中的网路编程主要是Java的Socket编程,属于JavaEE中的高级的部分,以下内容是对java网路编程的一个小结,代码都是经过编译调试的   C/S程序应用:客户/服务器模式,如QQ客户端,客户端连到服务器上,一个C/S模式的应用必须有两套程序,一个是客户端的程序,一个是服务器程序. B/S程序应用:浏览器/服务器模式,如当下的各种网站都是B/S模式,所有的程序代码都在服务器上,用户通过浏览器去访问.   C/S程序分为两种:         基于TCP协议:Socket(套接字

QT分析之网络编程(五)

今天分析QNetworkAccessManager.QNetworkRequest和QNetworkReply组成的高级抽象API序列.在动手之前,把doc中有关QNetworkAccessManager的介绍看了一遍.其使用方法大致是: QNetworkAccessManager * manager = new QNetworkAccessManager(this); QNetworkRequest request; request.setUrl(QUrl("http://www.baidu.

QT分析之网络编程(二)

前面分析(一)之前没有看QT自带的文档,看了doc之后对QT的网络体系有一个大致的了解: QNatvieSocketEnginePrivate是OS相关的API封装,和QNativeSocketEngine一起构成具体平台SOCKET实现: QTcpSocket.QUdpSocket.QTcpServer构成底层的应用API:QSslSocket是SSL加密相关API: QHttp.QFtp构成高层次应该API: QNetworkAccessManager.QNetworkRequest.QNe

QT分析之网络编程(八)

话说昨日走到QNetworkReplyImplPrivate::_q_startOperation(),勾引出QNetworkAccessHttpBackend::open(),今日接着欣赏QT之美丽. void QNetworkAccessHttpBackend::open() {     QUrl url = request().url();     bool encrypt = url.scheme().toLower() == QLatin1String("https");  

QT分析之网络编程(四)

前面分析中,一个问题一直没有解决:新生成的SOCKET是什么时候加入WSASelect()的?另外还有一个不是很大的问题,close流程. 在QEventDispatcherWin32Private::doWsaAsyncSelect()中WSAAsyncSelect()设置一个断点,观察call stack: >    QtCored4.dll!QEventDispatcherWin32Private::doWsaAsyncSelect(int socket=0x00001628)  行633

QT分析之网络编程(七)

接上面,进一步分析QNetworkAccessManager::createRequest()的实现.去除不重要的分支末节,看其调用的QNetworkReplyImplPrivate::setup()和QNetworkAccessManagerPrivate::findBackend()的代码. void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req,