目录
前言:
Linux下的TCP通信
QT下的TCP通信
服务器
ui
头文件
cpp文件
客户端
新建文件
编辑 ui
头文件.h
cpp文件
现象
Linux下的UDP通信
QT下的UDP通信
ui
工程文件
头文件.h
.cpp文件
现象
前言:

Linux下的TCP通信

socket,客户端,监听套接字
bind,绑定,固定端口,否则会随机
listen,监听,服务器端
accept,通信套接字
read/write
QT下的TCP通信

QTcpSocket 客户端
connectToHost()主动和服务器
如果连接成功,服务器会收到newConnection()→ newConnection()
发送数据,write →→
如果成功和对方建立好连接,通信套接字会自动触发connected(),
如果对方主动断开连接,通信套接字会自动触发disconnected(),
QTcpServer 服务器
listen()绑定好
如果连接成功,服务器会收到/触发,newConnection()→槽函数
槽函数,→取出建立好连接的套接字,QTcpSocket(通信套接字)
→→如果数据传输成功,对方的通信套接字会触发 readyRead(),需要在对应的槽函数做接收处理
网络编程
QT +=network;
服务器
ui
头文件
#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H
#include <QWidget>
#include <QTcpServer>//监听套接字
#include <QTcpSocket>//通信套接字
QT_BEGIN_NAMESPACE
namespace Ui { class ServerWidget; }
QT_END_NAMESPACE
class ServerWidget : public QWidget
{
Q_OBJECT
public:
ServerWidget(QWidget *parent = nullptr);
~ServerWidget();
private slots:
void on_pushButtonSend_clicked();
void on_ButtonClose_clicked();
private:
Ui::ServerWidget *ui;
QTcpServer *tcpServer;//监听套接字
QTcpSocket *tcpSocket;//通信套接字
};
#endif // SERVERWIDGET_H
cpp文件
#include "serverwidget.h"
#include "ui_serverwidget.h"
ServerWidget::ServerWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::ServerWidget)
{
ui->setupUi(this);
tcpServer =NULL;
tcpSocket =NULL;
//监听套接字
tcpServer =new QTcpServer(this);//指定父对象,可以让他自动回收空间
//绑定我当前网卡的所有ip
tcpServer->listen(QHostAddress::Any,8888);
setWindowTitle("服务器:8888");
connect(tcpServer,&QTcpServer::newConnection,
[=]()
{
//取出建立好连接的套接字
tcpSocket = tcpServer->nextPendingConnection();
//获取对方的ip和端口
QString ip = tcpSocket->peerAddress().toString();
qint16 port = tcpSocket->peerPort();
QString temp =QString("[%1:%2]:成功连接").arg(ip).arg(port);
ui->textEditRead->setText(temp);
//还没连接,无法取出,tcpSocket没有分配空间,只是个指针
connect(tcpSocket,&QTcpSocket::readyRead,
[=]()
{
//从通信套接字取出内容
QByteArray array = tcpSocket->readAll();
ui->textEditRead->append(array);
});
});
}
ServerWidget::~ServerWidget()
{
delete ui;
}
void ServerWidget::on_pushButtonSend_clicked()
{
if(NULL == tcpSocket)
{
return;
}
//获取编辑区内容
QString str=ui->textEditWrite->toPlainText();
//给对方发送数据,使用套接字tcpSocket
//
tcpSocket->write(str.toUtf8().data());
}
void ServerWidget::on_ButtonClose_clicked()
{
if(NULL == tcpSocket)
{
return;
}
//主动和客户端断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close();
tcpSocket =NULL;
}
客户端
新建文件
自带一个ui界面
ui
头文件.h
#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H
#include <QWidget>
#include <QTcpSocket>//通信套接字
namespace Ui {
class ClientWidget;
}
class ClientWidget : public QWidget
{
Q_OBJECT
public:
explicit ClientWidget(QWidget *parent = nullptr);
~ClientWidget();
private slots:
void on_Buttonconnect_clicked();
void on_ButtonSend_clicked();
private:
Ui::ClientWidget *ui;
QTcpSocket *tcpSocket;
};
#endif // CLIENTWIDGET_H
cpp文件
#include "clientwidget.h"
#include "ui_clientwidget.h"
#include<QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ClientWidget)
{
ui->setupUi(this);
tcpSocket =NULL;
//分配空间,指定父对象
tcpSocket =new QTcpSocket(this);
connect(tcpSocket,&QTcpSocket::connected,
[=]()
{
ui->textEditRead->setText("成功和服务器建立好连接");
});
connect(tcpSocket,&QTcpSocket::readyRead,
[=]()
{
//获取对方发送的内容
QByteArray array = tcpSocket->readAll();
//追加到编辑区中
ui->textEditRead ->append(array);
});
}
ClientWidget::~ClientWidget()
{
delete ui;
}
void ClientWidget::on_Buttonconnect_clicked()
{
//获取服务器ip和端口
QString ip =ui->lineEditIP->text();
qint16 port = ui->lineEdit8888 ->text().toInt();
//主动和服务器建立连接
tcpSocket->connectToHost(QHostAddress(ip),port);
}
void ClientWidget::on_ButtonSend_clicked()
{
//获取编辑框内容
QString str =ui->textEditWrite->toPlainText();
//发生数据
tcpSocket -> write( str.toUtf8().data());
}
void ClientWidget::on_ButtonClose_clicked()
{
//主动和对方断开连接
tcpSocket->disconnectFromHost();
}
现象
Linux下的UDP通信
无连接,绑定就直接发
TCP像打电话,UDP像写信
QT下的UDP通信
跟TCP比,没有监听过程
绑定了端口就可以发
ui
工程文件
QT += core gui network
头文件.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QUdpSocket>//UDP套接字
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void dealMsyg();
private slots:
void on_ButtonSend_clicked();
private:
Ui::Widget *ui;
QUdpSocket *udpSocket;
};
#endif // WIDGET_H
.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QUdpSocket>
#include <QHostAddress>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//分配空间,指定父对象
udpSocket = new QUdpSocket(this);
//绑定
//udpSocket->bind(8888);
udpSocket->bind(QHostAddress::AnyIPv4,8888);
//加入某个组播
//组播地址是D类地址
//udpSocket ->joinMulticastGroup(QHostAddress("172.18.107.20"));
//udpSocket->leaveMulticastGroup();//退出组播
//标题
setWindowTitle("服务器端口为:8888");
//当对方成功发送数据过来
//自动触发 readyRead()
connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::dealMsyg);
}
void Widget::dealMsyg()
{
//读取对方发生的内容
char buf[1024]={0};
QHostAddress cliAddr;//对方地址
quint16 port;//对方端口
quint64 len = udpSocket->readDatagram(buf,sizeof(buf),&cliAddr,&port);
if(len>0)
{
//格式化 []
QString str = QString("[%1,%2] %3")
.arg(cliAddr.toString())
.arg(port)
.arg(buf);
//给编辑区设置内容
ui->textEdit->setText(str);
}
}
Widget::~Widget()
{
delete ui;
}
//发送数据
void Widget::on_ButtonSend_clicked()
{
//获取对方ip和端口
QString ip=ui->lineEditIP->text();
quint16 port = ui->lineEditPort->text().toInt();
//获取编辑区内容
QString str = ui->textEdit->toPlainText();
//qDebug()<<str.toUtf8()<<QHostAddress(ip)<<port;
//给指定ip发送数据
udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
}
现象
我直接在原工程文件上建立了两个UDP
但是,两个UDP不能绑定同一个ip,将其中一个改为公用ip即可
//绑定
udpSocket->bind(9000);
//udpSocket->bind(QHostAddress::AnyIPv4,9000);
//加入某个组播
//组播地址是D类地址
udpSocket ->joinMulticastGroup(QHostAddress("255.255.255.255"));
//udpSocket->leaveMulticastGroup();//退出组播
现象同TCP类似