23TCP通信
.pro 文件中加入:QT+=network
在Qt中实现TCP/IP服务器端通信的流程:
1.创建监听套接字,QTcpServer
2.将监听套接字设置为监听模式, listen
3.等待并接受客户端请求,可以通过QTcpServer提供的void newConnection()信号来检测是否有连接请求,如果有可以在对应的槽函数中调用nextPendingConnection函数获取到客户端的Socket信息(返回值为QTcpSocket*类型指针),通过此套接字与客户端之间进行通信。此时会返回一个通信套接字,QTcpSocket
4.接收或者向客户端发送数据
5.接收数据:使用read()或者readAll()函数
6.发送数据:使用write()函数
监听套接字和通信套接字的区别:
在服务端包含两种套接字QTcpServer,QTcpSocket. QTcpServer用于listen()监听模式,监听哪个IP,从哪个端口接入。QTcpSocket用于两者之间的真正通信,当两者完成连接后,各个都拥有一个QTcpSocket,如:sock1,sock1,那么这两个通信套接字等同于各自的手机号码,用于通信使用。
客户端通信流程:
1.创建套接字
2.连接服务器,可以使用QTcpSocket类的connectToHost()函数来连接服务器。
3.向服务器发送或者接受数据
如图:

解析:当服务端处于监听模式时(listen),客户端通过connectToHost请求连接,此时服务端就是触发信号newConnection(系统给出,非自拟),调用对应的槽函数(可自拟,或直接使用Lambda表达式)。服务端连通后,客户端就会立即触发信号connected.说明两者之间已完成连接,彼此可以利用write发出信息,利用read,readAll接受信息。
服务器
TcpSever.h
#ifndef TCPSEVER_H
#define TCPSEVER_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_clicked(); //发送按钮
void on_pushButton_2_clicked(); //关闭通信
private:
Ui::Widget *ui;
QTcpServer *m_server; //监听套接字
QTcpSocket *m_ServerSock; //通信套接字
};
#endif // TCPSEVER_H
TcpSever.cpp
#include "TcpSever.h"
#include "ui_widget.h"
#include <QTime>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//监听套接字,指定父对象,让其自动回收空间
m_server=new QTcpServer(this);
m_ServerSock=NULL;
this->setWindowTitle("服务器端口:888");
//监听IP地址,指定端口
m_server->listen(QHostAddress::Any,888);
//客户端接入触发
connect(m_server,&QTcpServer::newConnection,
[=]() mutable
{
if(m_ServerSock==NULL)
{
//取出建立好的连接的套接字
m_ServerSock=m_server->nextPendingConnection();
//获取对方的IP,端口号
QString strIP=m_ServerSock->peerAddress().toString();
quint16 uPort=m_ServerSock->peerPort();
//newConnection信号被触发后,显示有客户端接入
//m_ServerSock->write("连接成功!!!");
ui->edit_Recv->setText(QString("[%1,%2]接入成功").arg(strIP).arg(uPort));
//通信
connect(m_ServerSock,&QTcpSocket::readyRead,
[=]() mutable
{
//接受对方发来的信息
QByteArray byteBuf=m_ServerSock->readAll();
//获取本地时间
QTime time=QTime::currentTime();
//显示在消息框,append不断追加
QString strTemp=time.toString()+QString("::")+QString(byteBuf);
ui->edit_Recv->append(QString(strTemp));
}
);
}
}
);
}
Widget::~Widget()
{
delete ui;
delete m_server;
m_server=NULL;
m_ServerSock=NULL;
}
void Widget::on_pushButton_clicked()
{
if(m_ServerSock!=NULL)
{
//获取要发送的信息
QString strSend=ui->edit_Send->toPlainText();
//发送
m_ServerSock->write(strSend.toUtf8().data());
//清空发送框的内容
//ui->edit_Send->clear();
}
}
void Widget::on_pushButton_2_clicked()
{
if(m_ServerSock!=NULL)
{
//断开连接
m_ServerSock->disconnectFromHost();
m_ServerSock->close();
m_server->close();
}
}
同一程序添加两个窗口,且有设计器。新建一个文件,但不是C++类文件,而是QT且带有界面类的,最后在main中使用show()直接显示。如下图:

客户端
tcpclient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QWidget>
#include <QTcpSocket>
#include <QHostAddress>
namespace Ui {
class TcpClient;
}
class TcpClient : public QWidget
{
Q_OBJECT
public:
explicit TcpClient(QWidget *parent = 0);
~TcpClient();
private slots:
void on_connect_clicked(); //请求服务器连接
void on_send_clicked(); //发送信息
void on_close_clicked(); //关闭通信
private:
Ui::TcpClient *ui;
QTcpSocket *m_ClientSock; //通信套接字
};
#endif // TCPCLIENT_H
tcpclient.cpp
#include "tcpclient.h"
#include "ui_tcpclient.h"
#include <QDebug>
#include <QTime>
TcpClient::TcpClient(QWidget *parent) :
QWidget(parent),
ui(new Ui::TcpClient)
{
ui->setupUi(this);
this->setWindowTitle("客户端");
//便于调试
//ui->IP->setText("127.0.0.1");
//ui->Port->setText("888");
//分配空间,指定父对象
m_ClientSock=new QTcpSocket(this);
//与服务器连接好触发
connect(m_ClientSock,&QTcpSocket::connected,
[=]() mutable
{
ui->clientRecv->setText("成功连接!!!");
//通信
connect(m_ClientSock,&QTcpSocket::readyRead,
[=]()
{
//获取对方发来的信息
QByteArray byteBuf=m_ClientSock->readAll();
//获取本地时间
QTime time=QTime::currentTime();
//显示在消息框,append不断追加
QString strTemp=time.toString()+QString("::")+QString(byteBuf);
ui->clientRecv->append(strTemp);
}
);
}
);
// connect(m_ClientSock,QTcpSocket::disconnected(),
// []()
// {
// m_ClientSock->disconnectFromHost();
// m_ClientSock->close();
// }
// )
}
TcpClient::~TcpClient()
{
delete ui;
delete m_ClientSock;
m_ClientSock=NULL;
}
void TcpClient::on_connect_clicked()
{
//设置对方的IP,端口
QString strIP=ui->IP->text();
qint16 uPort=ui->Port->text().toInt();
//请求服务器连接
m_ClientSock->connectToHost(QHostAddress(strIP),uPort);
}
void TcpClient::on_send_clicked()
{
//获取要发送的信息
QString strSend=ui->clientSend->toPlainText();
//发送
m_ClientSock->write(strSend.toUtf8().data());
//清空
//ui->clientSend->clear();
}
void TcpClient::on_close_clicked()
{
//断开连接
m_ClientSock->disconnectFromHost();
m_ClientSock->close();
}
main.cpp
#include "TcpSever.h"
#include <QApplication>
#include "tcpclient.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
TcpClient c;
c.show();
return a.exec();
}
程序结果图:

23TCP通信的更多相关文章
- 理解加密算法(三)——创建CA机构,签发证书并开始TLS通信
		
接理解加密算法(一)--加密算法分类.理解加密算法(二)--TLS/SSL 1 不安全的TCP通信 普通的TCP通信数据是明文传输的,所以存在数据泄露和被篡改的风险,我们可以写一段测试代码试验一下. ...
 - 笔记:Binder通信机制
		
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
 - .NET 串口通信
		
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
 - MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
		
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
 - 多线程的通信和同步(Java并发编程的艺术--笔记)
		
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
 - 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
		
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
 - 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1
		
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...
 - TCP通信
		
//网络套接字编程实例,服务器端,TCP通信. #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #inc ...
 - JAVA通信系列一:Java Socket技术总结
		
本文是学习java Socket整理的资料,供参考. 1 Socket通信原理 1.1 ISO七层模型 1.2 TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...
 
随机推荐
- swift--使用 is 和 as 操作符来实现类型检查和转换 / AnyObject与Any的区别
			
声明几个类: //动物类 class Animal{ } //陆地动物类 class terricole: Animal { } //海洋动物类 class SeaAnimals: Animal { ...
 - swift - UISlider 的用法
			
swift的UISlider的用法和oc基本没有区别 1.创建 class SecondViewController: UIViewController { var slider = UISlider ...
 - Android中SurfaceView用法示例
			
SurfaceView在游戏开发中有着举足轻重的地位,它对于画面的控制有着更大的自由度(不像View要用handler来更新,关于View的),但这方面的参考资料并不是太多,能找到的例子都有点喧宾夺主 ...
 - Keil(MDK-ARM)在线调试(Ⅰ)(转)
			
Ⅰ.写在前面 Keil在线调试的内容有很多,本文带来在线调试常用的内容:Debug Toolbar调试工具栏(复位.全速运行.停止运行.单步调试.逐行调试.跳出调试.运行到光标行.跳转到暂停行.调试窗 ...
 - VC项目程序运行时设置指定目录读取Dll
			
方法一: 选择当前工程,右击"Properties" -> "Configuration Properties" -> "Debuggin ...
 - 上传控件CSS用图片代替
			
<style type="text/css"> a.btn {width: 120px;height: 42px;overflow: hidden;display: b ...
 - Androidの共享登录之方案研究
			
由于最近公司提到了一个需求是,一个应用登录成功了,另一个自动登录. 绞尽脑汁想了好几天,看起来很容易但是想深点就漏洞百出,有的时候代码都写完了测试都成功了突然发现给一个假设就完全失效. 先前几个同事之 ...
 - activemq 实战二 连接到ActiveMQ-Connecting to ActiveMQ
			
The main role of a JMS broker such as ActiveMQ is to provide a communication infrastructure for clie ...
 - etc/fstab
			
etc/fstab 就是在开机引导的时候自动挂载到linux的文件系统 设备名称 挂载点 分区的类型 挂载选项 dump选项 fsck选项UUID=ce25cdc7-434f-420b-b3 / ex ...
 - Oracle卸载之linux快速卸载rac脚本-一键卸载
			
#!/bin/bash#Usage:Log on as the superuser('root') on node1,node2 cd /u01/app/11.2.0/grid/bin./crsctl ...