Qt-Day12-学习笔记


区别:
在这里插入图片描述
recv + accpet == recvfrom
Send + connect == sendto

1. windows的UDP编程模型

在这里插入图片描述
客户端:

#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib ")
#include <windows.h>
#include <stdio.h>

int main(){
	//0 请求协议版本
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2){
		printf("请求协议版本失败:%d\n", GetLastError());
		return -1;
	}
	printf("请求协议版本成功!\n");

	//1 创建socket
	SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (SOCKET_ERROR == serverSocket){
		printf("创建socket失败:%d\n", GetLastError());
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("创建socket成功!\n");

	//2 服务器协议地址簇
	SOCKADDR_IN sAddr = { 0 };
	sAddr.sin_family = AF_INET;								// 和socket第一个参数一致
	sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 把数点格式字符串转换成网络字节序
	sAddr.sin_port = htons(10086);							// 65536   5000以上    大小端转换

	//3 绑定
	int r = bind(serverSocket, (sockaddr*)&sAddr, sizeof sAddr);
	if (-1 == r){
		printf("绑定失败:%d\n", GetLastError());
		//7 关闭socket
		closesocket(serverSocket);
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("绑定成功!\n");


	//4 接收数据

	char buff[1024];

	//客户端协议地址簇
	SOCKADDR_IN cAddr = { 0 };
	int len = sizeof cAddr;
	while (1){
		r = recvfrom(serverSocket, buff, 1023, NULL,(sockaddr*)&cAddr,&len);
		if (r > 0){
			buff[r] = 0;
			printf(">>%s\n", buff);

			sendto(serverSocket, "砍死你个耙耳朵", strlen("砍死你个耙耳朵"), NULL,
				(sockaddr*)&cAddr, sizeof cAddr);
		}
	}


	//5 关闭socket
	closesocket(serverSocket);
	//6 清理协议版本信息
	WSACleanup();


	return 0;
}

服务器端:

#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib ")
#include <windows.h>
#include <stdio.h>

int main(){
	//0 请求协议版本
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2){
		printf("请求协议版本失败:%d\n", GetLastError());
		return -1;
	}
	printf("请求协议版本成功!\n");

	//1 创建socket
	SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (SOCKET_ERROR == serverSocket){
		printf("创建socket失败:%d\n", GetLastError());
		//8 清理协议版本信息
		WSACleanup();
		return -1;
	}
	printf("创建socket成功!\n");

	//2 服务器协议地址簇
	SOCKADDR_IN sAddr = { 0 };
	sAddr.sin_family = AF_INET;								// 和socket第一个参数一致
	sAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	// 把数点格式字符串转换成网络字节序
	sAddr.sin_port = htons(10086);							// 65536   5000以上    大小端转换

	
	//3 发送数据到服务器   sendto
	char buff[1024];
	int r;
	char temp[1024];
	while (1){
		printf("请输入:");
		scanf("%s", buff);
		sendto(serverSocket, buff, strlen(buff), NULL, //炮弹       一瓶水
			(sockaddr*)&sAddr, sizeof sAddr);			//向谁发炮  往哪扔
		r = recv(serverSocket, temp, 1023, NULL);
		if (r > 0){
			temp[r] = 0;
			printf("来自服务器的问候:%s\n", temp);
		}
	}


	//4 关闭socket
	closesocket(serverSocket);
	//5 清理协议版本信息
	WSACleanup();


	return 0;
}

在这里插入图片描述
在这里插入图片描述

2. Qt的UDP编程模型

在这里插入图片描述
客户端:

#include "clientwidget.h"
#include "ui_clientwidget.h"

clientwidget::clientwidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::clientwidget)
{
    ui->setupUi(this);

    setWindowTitle("udp客户端 ");

    //1. 创建socket
    pUdpSocket = new QUdpSocket(this);

    //2. 收数据
    connect(pUdpSocket,&QUdpSocket::readyRead,
            [=](){
        //2.1. 接收
        char buff[1024] = {0};
        QHostAddress ip;
        quint16 port;
        //recvForm
        pUdpSocket->readDatagram(buff,1024,&ip,&port);

        //2.2. 显示
        QString str = QString("ip:%1,port:%2,msg:%3").
                arg(ip.toString()).arg(port).arg(buff);

        ui->textEdit_Recv->append(str);
    });
}

clientwidget::~clientwidget()
{
    delete ui;
}

void clientwidget::on_btn_Send_clicked()
{
//3.1. 获取port和ip
    QString ip = ui->lineEdit_IP->text();
    QString port = ui->lineEdit_Port->text();

    QString msg = ui->textEdit_Send->toPlainText();

    pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}


服务器端:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    setWindowTitle("udp服务器 ");

    //1. 创建socket
    pUdpSocket = new QUdpSocket(this);
    //2. 绑定
    //pUdpSocket->bind(8888);

    //4.0. 设置组播
        //4.1. 绑定,任意地址
    pUdpSocket->bind(QHostAddress::AnyIPv4,9999);
        //4.2. 进组
    pUdpSocket->joinMulticastGroup(QHostAddress("224.0.0.3"));
    pUdpSocket->joinMulticastGroup(QHostAddress("224.0.0.4"));
    //3. 收数据
    connect(pUdpSocket,&QUdpSocket::readyRead,
            [=](){
        //3.1. 接收
        char buff[1024] = {0};
        QHostAddress ip;
        quint16 port;
        //recvForm
        pUdpSocket->readDatagram(buff,1024,&ip,&port);

        //3.2. 显示
        QString str = QString("ip:%1,port:%2,msg:%3").arg(ip.toString()).
                arg(port).arg(buff);

        ui->textEdit_Recv->append(str);
    });
}

Widget::~Widget()
{
    delete ui;
}

//4. 发送数据
void Widget::on_btn_Send_clicked()
{
    //4.1. 获取port和ip
    QString ip = ui->lineEdit_IP->text();
    QString port = ui->lineEdit_Port->text();

    QString msg = ui->textEdit_Send->toPlainText();

    pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}

在这里插入图片描述

D类地址:
组播组可以是永久的也可以是临时的。
组播组地址中,有一部分由官方分配的,称为永久组播组。
永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。
永久组播组中成员的数量都可以是任意的,甚至可以为零。
那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

  • 224.0.0.0~224.0.0.255
    为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;

  • 224.0.1.0~224.0.1.255
    是公用组播地址,可以用于Internet;

  • 224.0.2.0~238.255.255.255
    为用户可用的组播地址(临时组地址),全网范围内有效;

  • 239.0.0.0~239.255.255.255
    为本地管理组播地址,仅在特定的本地范围内有效。

3. 点播,广播,组播

在这里插入图片描述

4. 程序打包

  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述

总结

  • C/C++ Qt 跨平台
  • 几乎所有的操作系统都是用C/C++来写的
  • 源文件->编译->链接->可执行程序文件
  • 到处编译到处运行
  • windows上,用windows的编译器来编译,然后运行
  • Linux上,用Linux的编译器来编译,然后运行
  • Java的跨平台缘由
    Java虚拟机:C++写的:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值